Re: Beos updates - Mailing list pgsql-patches

From Bruce Momjian
Subject Re: Beos updates
Date
Msg-id 200010281826.OAA14596@candle.pha.pa.us
Whole thread Raw
List pgsql-patches
Applied.  Thanks.


[ Charset ISO-8859-1 unsupported, converting... ]
> >
> >This doesn't work.  There is strange wrapping.  I don't care how big
> the
> >context diff is.  Send it.
> >
>
>     OK here is the complet diff against the current tree (I also
> attached it to the message).
>
>
>         cyril
>
>
>
> *** ./src/backend/port/beos/sem.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/sem.c    Tue Oct 10 22:21:35 2000
> ***************
> *** 13,172 ****
>   #include <stdio.h>
>   #include <errno.h>
>   #include <OS.h>
>
> - // Controle d'un pool de s?maphores
> - // On considere que le semId utilis? correspond bien a une area de
> notre adress space
> - // Les informations du pool de s?maphore sont stock?s dans cette area
>   int semctl(int semId,int semNum,int flag,union semun semun)
>   {
> -
> -     // Recherche de l'adresse de base de l'area
>       int32* Address;
>       area_info info;
> ! //    printf("semctl : semid  %d, semnum %d, cmd %d\
> n",semId,semNum,flag);
>       if (get_area_info(semId,&info)!=B_OK)
>       {
> ! //        printf("area not found\n");
>           errno=EINVAL;
>           return -1;
>       }
>       Address=(int32*)info.address;
>
> -     // semnum peut etre ?gal ? 0
> -     // semun.array contient la valeur de d?part du s?maphore
>
> !     // si flag = set_all il faut d?finir la valeur du s?maphore sue
> semun.array
>       if (flag==SETALL)
>       {
>           long i;
> - //        printf("setall %d\n",Address[0]);
>           for (i=0;i<Address[0];i++)
>           {
>               int32 cnt;
>               get_sem_count(Address[i+1],&cnt);
> ! //            printf("Set de ALl %d  %d = %d\n",Address[i+
> 1],semun.array[i],cnt);
>               cnt-=semun.array[i];
>               if (cnt > 0)
> !                 acquire_sem_etc(Address[i+1],cnt,0,0);
>               if (cnt < 0)
>                   release_sem_etc(Address[i+1],-cnt,0);
>           }
>           return 1;
>       }
>
> !     /* si flag = SET_VAL il faut d?finir la valeur du s?maphore sur
> semun.val*/
>       if (flag==SETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
> ! //        printf("semctl set val id : %d val : %d = %d\
> n",semId,semun.val,cnt);
>           cnt-=semun.val;
>           if (cnt > 0)
> !             acquire_sem_etc(Address[semNum+1],cnt,0,0);
>           if (cnt < 0)
>               release_sem_etc(Address[semNum+1],-cnt,0);
>           return 1;
>       }
>
> !     /* si flag=rm_id il faut supprimer le s?maphore*/
>       if (flag==IPC_RMID)
>       {
>           long i;
> !         // Suppression des s?maphores (ils appartienent au kernel
> maintenant)
>           thread_info ti;
> - //        printf("remove set\n");
>           get_thread_info(find_thread(NULL),&ti);
>           for (i=0;i<Address[0];i++)
>           {
>               set_sem_owner(Address[i+1],ti.team);
>               delete_sem(Address[i+1]);
>           }
> !         // Il faudrait supprimer en boucle toutes les area portant le
> m?me nom
>           delete_area(semId);
>           return 1;
>       }
>
> !     /* si flag = GETNCNT il faut renvoyer le semaphore count*/
>       if (flag==GETNCNT)
>       {
> ! //        printf("getncnt : impossible sur BeOS\n");
> !         return 0; // a faire (peut etre impossible sur Beos)
>       }
>
> !     /* si flag = GETVAL il faut renvoyer la valeur du s?maphore*/
>       if (flag==GETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
> - //        printf("semctl getval id : %d cnt : %d\n",semId,cnt);
>           return cnt;
>       }
> ! //    printf("semctl erreur\n");
>       return 0;
>   }
>
> ! // L'area dans laquelle est stock?e le pool est identifi?e par son
> nom (convention ? moi : SYSV_IPC_SEM : "semId)
>   int semget(int semKey, int semNum, int flags)
>   {
>       char Nom[50];
>       area_id parea;
>       void* Address;
>
> ! //    printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags);
> !     // Construction du nom que doit avoir l'area
>       sprintf(Nom,"SYSV_IPC_SEM : %d",semKey);
>
> !     // Recherche de l'area
>       parea=find_area(Nom);
>
> !     // L'area existe
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> ! //        printf("area found\n");
> !         // On demande une creatrion d'un pool existant : erreur
>           if ((flags&IPC_CREAT)&&(flags&IPC_EXCL))
>           {
> - //            printf("creat asking exist\n");
>               errno=EEXIST;
>               return -1;
>           }
>
> !         // Clone de l'area et renvoi de son ID
>           parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA |
> B_WRITE_AREA,parea);
>           return parea;
>       }
> -     // L'area n'existe pas
>       else
>       {
> ! //        printf("set don't exist\n");
> !         // Demande de creation
>           if (flags&IPC_CREAT)
>           {
>               int32* Address;
> -             thread_info ti;
>               void* Ad;
>               long i;
>
> ! //            printf("create set\n");
> !             // On ne peut pas creer plus de 500 semaphores dans un pool
> (limite tout ? fait arbitraire de ma part)
>               if (semNum>500)
>               {
>                   errno=ENOSPC;
>                   return -1;
>               }
> !
> !             // Creation de la zone de m?moire partag?e
>               parea=create_area(Nom,&
> Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
>               if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==
> B_ERROR))
>               {
>                   errno=ENOMEM;
>                   return -1;
>               }
>               Address=(int32*)Ad;
>               Address[0]=semNum;
>               for (i=1;i<=Address[0];i++)
>               {
> !                 // Creation des s?maphores 1 par 1
>                   Address[i]=create_sem(0,Nom);
>
>                   if ((Address[i]==B_BAD_VALUE)|| (Address[i]==
> B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS))
> --- 13,191 ----
>   #include <stdio.h>
>   #include <errno.h>
>   #include <OS.h>
 > + #include "utils/elog.h"
> +
> +
> + /* Control of a semaphore pool. The pool is an area in which we
> stored all
> + the semIds of the pool. The first 4 bytes are the number of semaphore
> allocated
> + in the pool followed by SemIds */
>
>   int semctl(int semId,int semNum,int flag,union semun semun)
>   {
>       int32* Address;
>       area_info info;
> !
> !     /* Try to find the pool */
>       if (get_area_info(semId,&info)!=B_OK)
>       {
> !         /* pool is invalid (BeOS area id is invalid) */
>           errno=EINVAL;
>           return -1;
>       }
> +
> +     /* Get the pool address */
>       Address=(int32*)info.address;
>
>
> !     /* semNum might be 0 */
> !     /* semun.array contain the sem initial values */
> !
> !     /* Fix the count of all sem of the pool to semun.array */
>       if (flag==SETALL)
>       {
>           long i;
>           for (i=0;i<Address[0];i++)
>           {
>               int32 cnt;
> +             /* Get the current count */
>               get_sem_count(Address[i+1],&cnt);
> !
> !             /* Compute and set the new count (relative to the old one)
> */
>               cnt-=semun.array[i];
>               if (cnt > 0)
> !                 while(acquire_sem_etc(Address[i+1],cnt,0,0)==
> B_INTERRUPTED);
>               if (cnt < 0)
>                   release_sem_etc(Address[i+1],-cnt,0);
>           }
>           return 1;
>       }
>
> !     /* Fix the count of one semaphore to semun.val */
>       if (flag==SETVAL)
>       {
>           int32 cnt;
> +         /* Get the current count */
>           get_sem_count(Address[semNum+1],&cnt);
> !
> !         /* Compute and set the new count (relative to the old one) */
>           cnt-=semun.val;
>           if (cnt > 0)
> !             while(acquire_sem_etc(Address[semNum+1],cnt,0,0)==
> B_INTERRUPTED);
>           if (cnt < 0)
>               release_sem_etc(Address[semNum+1],-cnt,0);
>           return 1;
>       }
>
> !     /* Delete the pool */
>       if (flag==IPC_RMID)
>       {
>           long i;
> !
>           thread_info ti;
>           get_thread_info(find_thread(NULL),&ti);
> +
> +         /* Loop over all semaphore to delete them */
>           for (i=0;i<Address[0];i++)
>           {
> +             /* Don't remember why I do that */
>               set_sem_owner(Address[i+1],ti.team);
> +
> +             /* Delete the semaphore */
>               delete_sem(Address[i+1]);
> +
> +             /* Reset to an invalid semId (in case other process try to
> get the infos from a cloned area */
> +             Address[i+1]=0;
>           }
> !
> !         /* Set the semaphore count to 0 */
> !         Address[0]=0;
> !
> !         /* Delete the area (it might be cloned by other process. Let
> them live with it,
> !         in all cases semIds are 0 so if another process try to use it,
> it will fail */
>           delete_area(semId);
> +
>           return 1;
>       }
>
> !     /* Get the current semaphore count */
>       if (flag==GETNCNT)
>       {
> !         /* TO BE IMPLEMENTED */
> !         elog(ERROR,"beos : semctl error : GETNCNT not implemented");
> !         return 0;
>       }
>
> !     /* Get the current semaphore count of the first semaphore in the
> pool */
>       if (flag==GETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
>           return cnt;
>       }
> !
> !     elog(ERROR,"beos : semctl error : unknown flag");
> !
>       return 0;
>   }
>
> ! /* Find a pool id based on IPC key */
>   int semget(int semKey, int semNum, int flags)
>   {
>       char Nom[50];
>       area_id parea;
>       void* Address;
>
> !     /* Name of the area to find */
>       sprintf(Nom,"SYSV_IPC_SEM : %d",semKey);
>
> !     /* find area */
>       parea=find_area(Nom);
>
> !     /* Test of area existance */
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> !         /* Area exist and creation is requested, error */
>           if ((flags&IPC_CREAT)&&(flags&IPC_EXCL))
>           {
>               errno=EEXIST;
>               return -1;
>           }
>
> !         /* Get an area clone (in case it's not in our address space) */
> !         /* TODO : a check of address space might be done to avoid
> duplicate areas in the same address space*/
>           parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA |
> B_WRITE_AREA,parea);
>           return parea;
>       }
>       else
>       {
> !         /* Area does not  exist, but creation is requested, so create
> it */
>           if (flags&IPC_CREAT)
>           {
>               int32* Address;
>               void* Ad;
>               long i;
>
> !             /* Limit to 500 semaphore in a pool */
>               if (semNum>500)
>               {
>                   errno=ENOSPC;
>                   return -1;
>               }
> !
> !             /* Create the shared memory area which will hold the pool *
> /
>               parea=create_area(Nom,&
> Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
>               if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==
> B_ERROR))
>               {
>                   errno=ENOMEM;
>                   return -1;
>               }
> +
> +             /* fill up informations (sem number and sem ids) */
>               Address=(int32*)Ad;
>               Address[0]=semNum;
>               for (i=1;i<=Address[0];i++)
>               {
> !                 /* Create the semaphores */
>                   Address[i]=create_sem(0,Nom);
>
>                   if ((Address[i]==B_BAD_VALUE)|| (Address[i]==
> B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS))
> ***************
> *** 176,219 ****
>                   }
>               }
>
> - //            printf("returned %d\n",parea);
>               return parea;
>           }
> -         // Le pool n'existe pas et pas de demande de cr?ation
>           else
>           {
> ! //            printf("set does not exist no creat requested\n");
>               errno=ENOENT;
>               return -1;
>           }
>       }
>   }
>
> ! // Op?ration sur le pool de s?maphores
>   int semop(int semId, struct sembuf *sops, int nsops)
>   {
> !     // Recherche de l'adresse du pool
> !     int32* Address;
>          area_info info;
>       long i;
>
> ! //    printf("semop id : %d n: %d\n",semId,sops->sem_op);
>       get_area_info(semId,&info);
>       Address=(int32*)info.address;
>       if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR))
>       {
>           errno=EINVAL;
>           return -1;
>       }
>
> !     // Execution de l'action
>       for(i=0;i<nsops;i++)
>       {
> !
> ! //        printf("semid %d, n %d\n",Address[sops[i].sem_num+
> 1],sops[i].sem_op);
>           if (sops[i].sem_op < 0)
>           {
> !             acquire_sem_etc(Address[sops[i].sem_num+1],-
> sops[i].sem_op,0,0);
>           }
>           if (sops[i].sem_op > 0)
>           {
> --- 195,237 ----
>                   }
>               }
>
>               return parea;
>           }
>           else
>           {
> !             /* Area does not exist and no creation is requested */
>               errno=ENOENT;
>               return -1;
>           }
>       }
>   }
>
> ! /* Acquire or release in the semaphore pool */
>   int semop(int semId, struct sembuf *sops, int nsops)
>   {
> !     int32* Address; /*Pool address*/
>          area_info info;
>       long i;
>
> !     /* Get the pool address (semId IS an area id) */
>       get_area_info(semId,&info);
>       Address=(int32*)info.address;
> +
> +     /* Check the validity of semId (it should be an area id) */
>       if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR))
>       {
>           errno=EINVAL;
>           return -1;
>       }
>
> !     /* Perform acquire or release */
>       for(i=0;i<nsops;i++)
>       {
> !         /* For each sem in the pool, check the operation to perform */
>           if (sops[i].sem_op < 0)
>           {
> !             /* Try acuiring the semaphore till we are not inteerupted
> by a signal */
> !             while (acquire_sem_etc(Address[sops[i].sem_num+1],-
> sops[i].sem_op,0,0)==B_INTERRUPTED);
>           }
>           if (sops[i].sem_op > 0)
>           {
> *** ./src/backend/port/beos/shm.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/shm.c    Tue Oct 10 23:18:00 2000
> ***************
> *** 12,37 ****
>   #include <stdio.h>
>   #include <OS.h>
>
> ! // Detachement d'une zone de m?moire partag?e
> ! // On detruit le clone de l'area dans notre adress-space
>   int shmdt(char* shmaddr)
>   {
> !     // Recherche de l'id de l'area pr?sente ? cette adresse
>       area_id s;
>       s=area_for(shmaddr);
> ! //    printf("detach area %d\n",s);
> !
> !     // Suppression de l'area
>       return delete_area(s);
>   }
>
> ! // Attachement ? une zone de m?moire partag?e
> ! // L'area doit bien partie de notre adress-space et on retourne
> directement l'adress
>   int* shmat(int memId,int m1,int m2)
>   {
> ! //    printf("shmat %d %d %d\n",memId,m1,m2);
> !
> !     // Lecture de notre team_id
>       thread_info thinfo;
>       team_info teinfo;
>       area_info ainfo;
> --- 12,36 ----
>   #include <stdio.h>
>   #include <OS.h>
>
> ! /* Emulating SYS shared memory with beos areas. WARNING : fork clone
> ! areas in copy on write mode */
> !
> !
> ! /* Detach from a shared mem area based on its address */
>   int shmdt(char* shmaddr)
>   {
> !     /* Find area id for this address */
>       area_id s;
>       s=area_for(shmaddr);
> !
> !     /* Delete area */
>       return delete_area(s);
>   }
>
> ! /* Attach to an existing area */
>   int* shmat(int memId,int m1,int m2)
>   {
> !     /* Get our team id */
>       thread_info thinfo;
>       team_info teinfo;
>       area_info ainfo;
> ***************
> *** 39,112 ****
>       get_thread_info(find_thread(NULL),&thinfo);
>       get_team_info(thinfo.team,&teinfo);
>
> !     // Lecture du teamid de l'area
>       if (get_area_info(memId,&ainfo)!=B_OK)
>           printf("AREA %d Invalide\n",memId);
>
>       if (ainfo.team==teinfo.team)
>       {
> !         //retour de l'adresse
> ! //        printf("attach area %d add %d\n",memId,ainfo.address);
>           return (int*)ainfo.address;
>       }
>       else
>       {
> !         // Clone de l'area
>           area_id narea;
>           narea = clone_area(ainfo.name,&
> (ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId);
>           get_area_info(narea,&ainfo);
> - //        printf("attach area %d in %d add %d\
> n",memId,narea,ainfo.address);
>           return (int*)ainfo.address;
>       }
>   }
>
> ! // Utilis? uniquement pour supprimer une zone de m?moire partag?e
> ! // On fait la meme chose que le detach mais avec un id direct
>   int shmctl(int shmid,int flag, struct shmid_ds* dummy)
>   {
> ! //    printf("shmctl %d %d \n",shmid,flag);
>       delete_area(shmid);
>       return 0;
>   }
>
> ! // Recup?ration d'une area en fonction de sa r?f?rence
> ! // L'area source est identifi?e par son nom (convention ? moi :
> SYSV_IPC_SHM : "memId)
>   int shmget(int memKey,int size,int flag)
>   {
> -     int32 n_size;
>       char nom[50];
> -     area_id parea;
>       void* Address;
> !     area_id a;
> !
> !     n_size=((size/4096)+1)*4096;
> !
> ! //    printf("shmget %d %d %d %d\n",memKey,size,flag,nsize);
>
> !     // Determination du nom que doit avoir l'area
>       sprintf(nom,"SYSV_IPC_SHM : %d",memKey);
>
> !
> !     // Recherche de cette area
>       parea=find_area(nom);
>
> !     // L'area existe
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> - //        printf("area found\n");
>           return parea;
>       }
>
> !     // L'area n'existe pas et on n'en demande pas la cr?ation : erreur
>       if (flag==0)
>       {
> - //        printf("area %s not found\n",nom);
>           return -1;
>       }
>
> !     // L'area n'existe pas mais on demande sa cr?ation
> !     a=create_area(nom,&
> Address,B_ANY_ADDRESS,n_size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
> ! //    printf("area %s : %d created addresse %d\n",nom,a,Address);
> !     return a;
>   }
>
> --- 38,96 ----
>       get_thread_info(find_thread(NULL),&thinfo);
>       get_team_info(thinfo.team,&teinfo);
>
> !     /* Get area teamid */
>       if (get_area_info(memId,&ainfo)!=B_OK)
>           printf("AREA %d Invalide\n",memId);
>
>       if (ainfo.team==teinfo.team)
>       {
> !         /* the area is already in our address space, just return the
> address */
>           return (int*)ainfo.address;
>       }
>       else
>       {
> !         /* the area is not in our address space, clone it before and
> return the address */
>           area_id narea;
>           narea = clone_area(ainfo.name,&
> (ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId);
>           get_area_info(narea,&ainfo);
>           return (int*)ainfo.address;
>       }
>   }
>
> ! /* Control a shared mem area : Used only to delete it */
>   int shmctl(int shmid,int flag, struct shmid_ds* dummy)
>   {
> !     /* Delete the area */
>       delete_area(shmid);
>       return 0;
>   }
>
> ! /* Get an area based on the IPC key */
>   int shmget(int memKey,int size,int flag)
>   {
>       char nom[50];
>       void* Address;
> !     area_id parea;
>
> !     /* Area name */
>       sprintf(nom,"SYSV_IPC_SHM : %d",memKey);
>
> !     /* Find area */
>       parea=find_area(nom);
>
> !     /* area exist, just return its id */
>       if (parea!=B_NAME_NOT_FOUND)
>       {
>           return parea;
>       }
>
> !     /* area does not exist and no creation is requested : error */
>       if (flag==0)
>       {
>           return -1;
>       }
>
> !     /* area does not exist and its creation is requested, create it (be
> sure to have a 4ko multiple size */
> !     return create_area(nom,&Address,B_ANY_ADDRESS,((size/4096)+1)*
> 4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
>   }
>
> *** ./src/backend/port/beos/support.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/support.c    Sun Oct 15 23:30:35 2000
> ***************
> *** 11,57 ****
>   #include "postgres.h"
>
>   /* Support Globals */
> - char* self_binary=NULL;
>   port_id beos_dl_port_in=0;
>   port_id beos_dl_port_out=0;
>   sem_id beos_shm_sem;
>
>   image_id beos_dl_open(char * filename)
>   {
>       image_id im;
>
> !     /* Start the support server */
> !     if (self_binary==NULL)
> !     {
> !         /* Can't start support server without binary name */
> !         elog(NOTICE, "Error loading BeOS support server : can't find
> binary");
> !         return B_ERROR;
> !     }
> !     else
>       {
> !         /* If a port doesn't exist, lauch support server */
>           if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>           {
> !             /* Create communication port */
> !             beos_dl_port_in=create_port(50,"beos_support_in");
> !             beos_dl_port_out=create_port(50,"beos_support_in");
> !
>
> !             if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
> !             {
> !                 elog(NOTICE, "Error loading BeOS support server : can't
> create communication ports");
> !                 return B_ERROR;
> !             }
> !             else
> !             {
> !                 char Cmd[4000];
> !
> !                 /* Build arg list */
> !                 sprintf(Cmd,"%s -beossupportserver %d %d &
> ",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out);
> !
> !                 /* Lauch process */
> !                 system(Cmd);
> !             }
>           }
>       }
>
> --- 11,58 ----
>   #include "postgres.h"
>
>   /* Support Globals */
>   port_id beos_dl_port_in=0;
>   port_id beos_dl_port_out=0;
>   sem_id beos_shm_sem;
>
> + /* Global var containing the postgres path */
> + extern char        pg_pathname[];
> +
> +
> + /* Shared library loading doesn't work after fork in beos. The
> solution is to use an exact
> + copy of the process and use it to perform the loading, then just map
> the Text and Data segment
> + of the add-on in our address space. Both process must have the exact
> same memory mapping, so
> + we use the postgres executable. When it's lauched with the -
> beossupportserver parameter, the
> + postgres executable just run a loop to wait command on a port. Its
> only action is to load the addon,
> + the beos_dl_open will then remap the good areas in the backend
> address space. */
> +
> +
>   image_id beos_dl_open(char * filename)
>   {
>       image_id im;
>
> !     /* If a port doesn't exist, lauch support server */
> !     if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>       {
> !         /* Create communication port */
> !         beos_dl_port_in=create_port(50,"beos_support_in");
> !         beos_dl_port_out=create_port(50,"beos_support_in");
> !
> !
>           if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>           {
> !             elog(NOTICE, "Error loading BeOS support server : can't
> create communication ports");
> !             return B_ERROR;
> !         }
> !         else
> !         {
> !             char Cmd[4000];
> !
> !             /* Build arg list */
> !             sprintf(Cmd,"%s -beossupportserver %d %d &
> ",pg_pathname,(int)beos_dl_port_in,(int)beos_dl_port_out);
>
> !             /* Lauch process */
> !             system(Cmd);
>           }
>       }
>
> ***************
> *** 132,143 ****
>   {
>       if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) -
> 10, "postmaster"))
>       {
> !         /* Shared memory cloning protection semaphore */
>           beos_shm_sem=create_sem(1,"beos_shm_sem");
>       }
>
>       if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
>       {
>           port_id port_in;
>           port_id port_out;
>
> --- 133,146 ----
>   {
>       if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) -
> 10, "postmaster"))
>       {
> !         /* We are in the postmaster, create the protection semaphore
> for shared mem remapping */
>           beos_shm_sem=create_sem(1,"beos_shm_sem");
>       }
>
>       if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
>       {
> +         /* We are in the support server, run it ... */
> +
>           port_id port_in;
>           port_id port_out;
>
> ***************
> *** 211,258 ****
>   }
>
>
> ! void beos_backend_startup(char * binary)
>   {
> -     team_id ct;
> -     thread_info inft;
>       char nom[50];
>       char nvnom[50];
>       area_info inf;
>       int32 cook=0;
>
> !     /* remember full path binary name to load dl*/
> !     self_binary=strdup(binary);
>
> !     /* find the current team */
> !     get_thread_info(find_thread(NULL),&inft);
> !     ct=inft.team;
> !
> !     /* find all area with a name begining by pgsql and destroy / clone
> then */
> !
> !     /* This operation must be done by only one backend at a time */
> !     if(acquire_sem(beos_shm_sem)==B_OK)
>       {
> !         while (get_next_area_info(0, &cook, &inf) == B_OK)
>           {
> !             strcpy(nom,inf.name);
> !             strcpy(nvnom,inf.name);
> !             nom[9]=0;
> !             nvnom[5]='i';
> !             if (!strcmp(nom,"SYSV_IPC_"))
> !             {
> !                 void* add;
> !                 area_id ar;
> !                 add=inf.address;
> !                 delete_area(inf.area);
> !                 ar=find_area(inf.name);
> !                 clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA|
> B_WRITE_AREA,ar);
> !             }
> !         }
> !         release_sem(beos_shm_sem);
> !     }
> !     else
> !     {
> !         /* Fatal error, exiting with error */
> !         exit(1);
> !     }
>   }
> --- 214,290 ----
>   }
>
>
> !
> ! /* The behavior of fork is borken on beos regarding shared memory. In
> fact
> ! all shared memory areas are clones in copy on write mode in the new
> process.
> !
> ! We need to do a remapping of these areas. Just afer the fork we
> performe the
> ! following actions :
> !
> !     * Find all areas with a name begining by SYS_V_IPC_ in our process
> !     (areas created by the SYSV IPC emulation functions). The name is
> !     followed by the IPC KEY in decimal format
> !
> !     * For each area we do :
> !
> !         * 1 : Get its name
> !         * 2 : destroy it
> !         * 3 : find another area with the exact same name
> !         * 4 : clone it in our address space with a different name
> !
> !     There is a race condition in 3-4 : if there two fork in a very
> short
> !     time, in step 3 we might end up with two areas with the same name,
> and no
> !     possibility to find the postmaster one. So the whole process is
> protected
> !     by a semaphore which is acquires just before the fork and released
> in case
> !     of fork failure or just after the end of the remapping.*/
> !
> ! void beos_before_backend_startup(void)
> ! {
> !     /* Just before forking, acquire the semaphore */
> !     if(acquire_sem(beos_shm_sem)!=B_OK)
> !         exit(1);         /* Fatal error, exiting with error */
> ! }
> !
> ! void beos_backend_startup_failed(void)
> ! {
> !     /* The foek failed, just release the semaphore */
> !     release_sem(beos_shm_sem);
> ! }
> !
> !
> ! void beos_backend_startup(void)
>   {
>       char nom[50];
>       char nvnom[50];
>       area_info inf;
>       int32 cook=0;
>
> !     /* Perform the remapping process */
>
> !     /* Loop in all our team areas */
> !     while (get_next_area_info(0, &cook, &inf) == B_OK)
>       {
> !         strcpy(nom,inf.name);
> !         strcpy(nvnom,inf.name);
> !         nom[9]=0;
> !         nvnom[5]='i';
> !         /* Is it a SYS V area ? */
> !         if (!strcmp(nom,"SYSV_IPC_"))
>           {
> !             void* area_address;
> !             area_id area_postmaster;
> !             /* Get the area address */
> !             area_address=inf.address;
> !             /* Destroy the bad area */
> !             delete_area(inf.area);
> !             /* Find the postmaster area */
> !             area_postmaster=find_area(inf.name);
> !             /* Clone it at the exact same address */
> !             clone_area(nvnom,&area_address,B_CLONE_ADDRESS,B_READ_AREA|
> B_WRITE_AREA,area_postmaster);
> !         }
> !     }
> !
> !     /* remapping done release semaphore to allow other backend to
> startup */
> !
> !     release_sem(beos_shm_sem);
>   }
> *** ./src/backend/postmaster/postmaster.c.orig    Sat Oct 28 01:42:23
> 2000
> --- ./src/backend/postmaster/postmaster.c    Sat Oct 28 01:43:53 2000
> ***************
> *** 1719,1726 ****
> --- 1719,1734 ----
>       fflush(stdout);
>       fflush(stderr);
>
> + #ifdef __BEOS__
> +     /* Specific beos actions before backend startup */
> +     beos_before_backend_startup();
> + #endif
>       if ((pid = fork()) == 0)
>       {                            /* child */
> + #ifdef __BEOS__
> +         /* Specific beos backend stratup actions */
> +         beos_backend_startup();
> + #endif
>           if (DoBackend(port))
>           {
>               fprintf(stderr, "%s child[%d]: BackendStartup: backend
> startup failed\n",
> ***************
> *** 1734,1739 ****
> --- 1742,1751 ----
>       /* in parent */
>       if (pid < 0)
>       {
> + #ifdef __BEOS__
> +         /* Specific beos backend stratup actions */
> +         beos_backend_startup_failed();
> + #endif
>           fprintf(stderr, "%s: BackendStartup: fork failed: %s\n",
>                   progname, strerror(errno));
>           return STATUS_ERROR;
> *** ./src/backend/tcop/postgres.c.orig    Sat Oct 28 18:31:06 2000
> --- ./src/backend/tcop/postgres.c    Sat Oct 28 18:31:30 2000
> ***************
> *** 1480,1490 ****
>
>       if (IsUnderPostmaster)
>       {
> - #ifdef __BEOS__
> -         /* Specific beos backend stratup actions */
> -         beos_backend_startup(argv[0]);
> - #endif
> -
>           /* noninteractive case: nothing should be left after switches *
> /
>           if (errs || argc != optind || DBName == NULL)
>           {
> --- 1480,1485 ----
> *** ./src/include/port/beos.h.orig    Sat Oct 28 18:28:38 2000
> --- ./src/include/port/beos.h    Sat Oct 28 02:02:17 2000
> ***************
> *** 1,4 ****
> --- 1,6 ----
>   #include <kernel/OS.h>
> + #include "kernel/image.h"
> +
>   #define USE_POSIX_TIME
>   #define HAS_TEST_AND_SET
>
> ***************
> *** 6,73 ****
>
>   #define AF_UNIX     1 /* no domain sockets on BeOS */
>
> ! #ifdef __cplusplus
> ! extern "C" {
> ! #endif
> !     #include "kernel/image.h"
> !
> !     #undef HAVE_UNION_SEMUN
> !     #define HAVE_UNION_SEMUN 1
> !     #undef HAVE_SYS_SEM_H
> !     #undef HAVE_SYS_SHM_H
> !
> !     union semun
> !     {
> !         int            val;
> !         struct semid_ds *buf;
> !         unsigned short *array;
> !     };
> !     /* SYS V emulation */
> !
> !     #define IPC_RMID 256
> !     #define IPC_CREAT 512
> !     #define IPC_EXCL 1024
> !     #define IPC_PRIVATE 234564
> !
> !     #define EACCESS 2048
> !     #define EIDRM 4096
> !
> !     #define SETALL 8192
> !     #define GETNCNT 16384
> !     #define GETVAL 65536
> !     #define SETVAL 131072
> !
> !     struct sembuf
> !     {
> !         int sem_flg;
> !         int sem_op;
> !         int sem_num;
> !     };
> !
> !     int semctl(int semId,int semNum,int flag,union semun);
> !     int semget(int semKey, int semNum, int flags);
> !     int semop(int semId, struct sembuf *sops, int flag);
> !
> !     struct shmid_ds
> !     {
> !         int            dummy;
> !     };
>
> !     int shmdt(char* shmaddr);
> !     int* shmat(int memId,int m1,int m2);
> !     int shmctl(int shmid,int flag, struct shmid_ds* dummy);
> !     int shmget(int memKey,int size,int flag);
> !
> !
> !     /* Support functions */
> !     /* Specific beos action made on postgres/postmaster startup */
> !     void beos_startup(int argc,char** argv);
> !     /* Load a shared library */
> !     image_id beos_dl_open(char * filename);
> !     /* UnLoad a shared library */
> !     status_t beos_dl_close(image_id im);
> !     /* Specific beos action made on backend startup */
> !     void beos_backend_startup(char* binary);
> ! #ifdef __cplusplus
> ! }
> ! #endif
> \ No newline at end of file
> --- 8,71 ----
>
>   #define AF_UNIX     1 /* no domain sockets on BeOS */
>
> ! /* SYS V emulation */
> !
> ! #undef HAVE_UNION_SEMUN
> ! #define HAVE_UNION_SEMUN 1
> !
> ! #define IPC_RMID 256
> ! #define IPC_CREAT 512
> ! #define IPC_EXCL 1024
> ! #define IPC_PRIVATE 234564
> !
> ! #define EACCESS 2048
> ! #define EIDRM 4096
> !
> ! #define SETALL 8192
> ! #define GETNCNT 16384
> ! #define GETVAL 65536
> ! #define SETVAL 131072
> !
> ! union semun
> ! {
> !     int            val;
> !     struct semid_ds *buf;
> !     unsigned short *array;
> ! };
> !
> ! struct sembuf
> ! {
> !     int sem_flg;
> !     int sem_op;
> !     int sem_num;
> ! };
> !
> ! struct shmid_ds
> ! {
> !     int            dummy;
> ! };
>
> ! int semctl(int semId,int semNum,int flag,union semun);
> ! int semget(int semKey, int semNum, int flags);
> ! int semop(int semId, struct sembuf *sops, int flag);
> !
> ! int shmdt(char* shmaddr);
> ! int* shmat(int memId,int m1,int m2);
> ! int shmctl(int shmid,int flag, struct shmid_ds* dummy);
> ! int shmget(int memKey,int size,int flag);
> !
> !
> ! /* Support functions */
> !
> ! /* Specific beos action made on postgres/postmaster startup */
> ! void beos_startup(int argc,char** argv);
> ! /* Load a shared library */
> ! image_id beos_dl_open(char * filename);
> ! /* UnLoad a shared library */
> ! status_t beos_dl_close(image_id im);
> ! /* Specific beos action made on backend startup */
> ! void beos_before_backend_startup(void);
> ! /* Specific beos action made on backend startup */
> ! void beos_backend_startup(void);
> ! /* Specific beos action made on backend startup failure*/
> ! void beos_backend_startup_failed(void);
>
>

> *** ./src/backend/port/beos/sem.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/sem.c    Tue Oct 10 22:21:35 2000
> ***************
> *** 13,172 ****
>   #include <stdio.h>
>   #include <errno.h>
>   #include <OS.h>
>
> - // Controle d'un pool de sémaphores
> - // On considere que le semId utilisé correspond bien a une area de notre adress space
> - // Les informations du pool de sémaphore sont stockés dans cette area
>   int semctl(int semId,int semNum,int flag,union semun semun)
>   {
> -
> -     // Recherche de l'adresse de base de l'area
>       int32* Address;
>       area_info info;
> ! //    printf("semctl : semid  %d, semnum %d, cmd %d\n",semId,semNum,flag);
>       if (get_area_info(semId,&info)!=B_OK)
>       {
> ! //        printf("area not found\n");
>           errno=EINVAL;
>           return -1;
>       }
>       Address=(int32*)info.address;
>
> -     // semnum peut etre égal à 0
> -     // semun.array contient la valeur de départ du sémaphore
>
> !     // si flag = set_all il faut définir la valeur du sémaphore sue semun.array
>       if (flag==SETALL)
>       {
>           long i;
> - //        printf("setall %d\n",Address[0]);
>           for (i=0;i<Address[0];i++)
>           {
>               int32 cnt;
>               get_sem_count(Address[i+1],&cnt);
> ! //            printf("Set de ALl %d  %d = %d\n",Address[i+1],semun.array[i],cnt);
>               cnt-=semun.array[i];
>               if (cnt > 0)
> !                 acquire_sem_etc(Address[i+1],cnt,0,0);
>               if (cnt < 0)
>                   release_sem_etc(Address[i+1],-cnt,0);
>           }
>           return 1;
>       }
>
> !     /* si flag = SET_VAL il faut définir la valeur du sémaphore sur semun.val*/
>       if (flag==SETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
> ! //        printf("semctl set val id : %d val : %d = %d\n",semId,semun.val,cnt);
>           cnt-=semun.val;
>           if (cnt > 0)
> !             acquire_sem_etc(Address[semNum+1],cnt,0,0);
>           if (cnt < 0)
>               release_sem_etc(Address[semNum+1],-cnt,0);
>           return 1;
>       }
>
> !     /* si flag=rm_id il faut supprimer le sémaphore*/
>       if (flag==IPC_RMID)
>       {
>           long i;
> !         // Suppression des sémaphores (ils appartienent au kernel maintenant)
>           thread_info ti;
> - //        printf("remove set\n");
>           get_thread_info(find_thread(NULL),&ti);
>           for (i=0;i<Address[0];i++)
>           {
>               set_sem_owner(Address[i+1],ti.team);
>               delete_sem(Address[i+1]);
>           }
> !         // Il faudrait supprimer en boucle toutes les area portant le même nom
>           delete_area(semId);
>           return 1;
>       }
>
> !     /* si flag = GETNCNT il faut renvoyer le semaphore count*/
>       if (flag==GETNCNT)
>       {
> ! //        printf("getncnt : impossible sur BeOS\n");
> !         return 0; // a faire (peut etre impossible sur Beos)
>       }
>
> !     /* si flag = GETVAL il faut renvoyer la valeur du sémaphore*/
>       if (flag==GETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
> - //        printf("semctl getval id : %d cnt : %d\n",semId,cnt);
>           return cnt;
>       }
> ! //    printf("semctl erreur\n");
>       return 0;
>   }
>
> ! // L'area dans laquelle est stockée le pool est identifiée par son nom (convention à moi : SYSV_IPC_SEM : "semId)
>   int semget(int semKey, int semNum, int flags)
>   {
>       char Nom[50];
>       area_id parea;
>       void* Address;
>
> ! //    printf("semget get k: %d n: %d fl:%d\n",semKey,semNum,flags);
> !     // Construction du nom que doit avoir l'area
>       sprintf(Nom,"SYSV_IPC_SEM : %d",semKey);
>
> !     // Recherche de l'area
>       parea=find_area(Nom);
>
> !     // L'area existe
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> ! //        printf("area found\n");
> !         // On demande une creatrion d'un pool existant : erreur
>           if ((flags&IPC_CREAT)&&(flags&IPC_EXCL))
>           {
> - //            printf("creat asking exist\n");
>               errno=EEXIST;
>               return -1;
>           }
>
> !         // Clone de l'area et renvoi de son ID
>           parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,parea);
>           return parea;
>       }
> -     // L'area n'existe pas
>       else
>       {
> ! //        printf("set don't exist\n");
> !         // Demande de creation
>           if (flags&IPC_CREAT)
>           {
>               int32* Address;
> -             thread_info ti;
>               void* Ad;
>               long i;
>
> ! //            printf("create set\n");
> !             // On ne peut pas creer plus de 500 semaphores dans un pool (limite tout à fait arbitraire de ma part)
>               if (semNum>500)
>               {
>                   errno=ENOSPC;
>                   return -1;
>               }
> !
> !             // Creation de la zone de mémoire partagée
>               parea=create_area(Nom,&Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
>               if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==B_ERROR))
>               {
>                   errno=ENOMEM;
>                   return -1;
>               }
>               Address=(int32*)Ad;
>               Address[0]=semNum;
>               for (i=1;i<=Address[0];i++)
>               {
> !                 // Creation des sémaphores 1 par 1
>                   Address[i]=create_sem(0,Nom);
>
>                   if ((Address[i]==B_BAD_VALUE)|| (Address[i]==B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS))
> --- 13,191 ----
>   #include <stdio.h>
>   #include <errno.h>
>   #include <OS.h>
> + #include "utils/elog.h"
> +
> +
> + /* Control of a semaphore pool. The pool is an area in which we stored all
> + the semIds of the pool. The first 4 bytes are the number of semaphore allocated
> + in the pool followed by SemIds */
>
>   int semctl(int semId,int semNum,int flag,union semun semun)
>   {
>       int32* Address;
>       area_info info;
> !
> !     /* Try to find the pool */
>       if (get_area_info(semId,&info)!=B_OK)
>       {
> !         /* pool is invalid (BeOS area id is invalid) */
>           errno=EINVAL;
>           return -1;
>       }
> +
> +     /* Get the pool address */
>       Address=(int32*)info.address;
>
>
> !     /* semNum might be 0 */
> !     /* semun.array contain the sem initial values */
> !
> !     /* Fix the count of all sem of the pool to semun.array */
>       if (flag==SETALL)
>       {
>           long i;
>           for (i=0;i<Address[0];i++)
>           {
>               int32 cnt;
> +             /* Get the current count */
>               get_sem_count(Address[i+1],&cnt);
> !
> !             /* Compute and set the new count (relative to the old one) */
>               cnt-=semun.array[i];
>               if (cnt > 0)
> !                 while(acquire_sem_etc(Address[i+1],cnt,0,0)==B_INTERRUPTED);
>               if (cnt < 0)
>                   release_sem_etc(Address[i+1],-cnt,0);
>           }
>           return 1;
>       }
>
> !     /* Fix the count of one semaphore to semun.val */
>       if (flag==SETVAL)
>       {
>           int32 cnt;
> +         /* Get the current count */
>           get_sem_count(Address[semNum+1],&cnt);
> !
> !         /* Compute and set the new count (relative to the old one) */
>           cnt-=semun.val;
>           if (cnt > 0)
> !             while(acquire_sem_etc(Address[semNum+1],cnt,0,0)==B_INTERRUPTED);
>           if (cnt < 0)
>               release_sem_etc(Address[semNum+1],-cnt,0);
>           return 1;
>       }
>
> !     /* Delete the pool */
>       if (flag==IPC_RMID)
>       {
>           long i;
> !
>           thread_info ti;
>           get_thread_info(find_thread(NULL),&ti);
> +
> +         /* Loop over all semaphore to delete them */
>           for (i=0;i<Address[0];i++)
>           {
> +             /* Don't remember why I do that */
>               set_sem_owner(Address[i+1],ti.team);
> +
> +             /* Delete the semaphore */
>               delete_sem(Address[i+1]);
> +
> +             /* Reset to an invalid semId (in case other process try to get the infos from a cloned area */
> +             Address[i+1]=0;
>           }
> !
> !         /* Set the semaphore count to 0 */
> !         Address[0]=0;
> !
> !         /* Delete the area (it might be cloned by other process. Let them live with it,
> !         in all cases semIds are 0 so if another process try to use it, it will fail */
>           delete_area(semId);
> +
>           return 1;
>       }
>
> !     /* Get the current semaphore count */
>       if (flag==GETNCNT)
>       {
> !         /* TO BE IMPLEMENTED */
> !         elog(ERROR,"beos : semctl error : GETNCNT not implemented");
> !         return 0;
>       }
>
> !     /* Get the current semaphore count of the first semaphore in the pool */
>       if (flag==GETVAL)
>       {
>           int32 cnt;
>           get_sem_count(Address[semNum+1],&cnt);
>           return cnt;
>       }
> !
> !     elog(ERROR,"beos : semctl error : unknown flag");
> !
>       return 0;
>   }
>
> ! /* Find a pool id based on IPC key */
>   int semget(int semKey, int semNum, int flags)
>   {
>       char Nom[50];
>       area_id parea;
>       void* Address;
>
> !     /* Name of the area to find */
>       sprintf(Nom,"SYSV_IPC_SEM : %d",semKey);
>
> !     /* find area */
>       parea=find_area(Nom);
>
> !     /* Test of area existance */
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> !         /* Area exist and creation is requested, error */
>           if ((flags&IPC_CREAT)&&(flags&IPC_EXCL))
>           {
>               errno=EEXIST;
>               return -1;
>           }
>
> !         /* Get an area clone (in case it's not in our address space) */
> !         /* TODO : a check of address space might be done to avoid duplicate areas in the same address space*/
>           parea=clone_area(Nom,&Address,B_ANY_ADDRESS,B_READ_AREA | B_WRITE_AREA,parea);
>           return parea;
>       }
>       else
>       {
> !         /* Area does not  exist, but creation is requested, so create it */
>           if (flags&IPC_CREAT)
>           {
>               int32* Address;
>               void* Ad;
>               long i;
>
> !             /* Limit to 500 semaphore in a pool */
>               if (semNum>500)
>               {
>                   errno=ENOSPC;
>                   return -1;
>               }
> !
> !             /* Create the shared memory area which will hold the pool */
>               parea=create_area(Nom,&Ad,B_ANY_ADDRESS,4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
>               if ((parea==B_BAD_VALUE)|| (parea==B_NO_MEMORY)||(parea==B_ERROR))
>               {
>                   errno=ENOMEM;
>                   return -1;
>               }
> +
> +             /* fill up informations (sem number and sem ids) */
>               Address=(int32*)Ad;
>               Address[0]=semNum;
>               for (i=1;i<=Address[0];i++)
>               {
> !                 /* Create the semaphores */
>                   Address[i]=create_sem(0,Nom);
>
>                   if ((Address[i]==B_BAD_VALUE)|| (Address[i]==B_NO_MEMORY)||(Address[i]==B_NO_MORE_SEMS))
> ***************
> *** 176,219 ****
>                   }
>               }
>
> - //            printf("returned %d\n",parea);
>               return parea;
>           }
> -         // Le pool n'existe pas et pas de demande de création
>           else
>           {
> ! //            printf("set does not exist no creat requested\n");
>               errno=ENOENT;
>               return -1;
>           }
>       }
>   }
>
> ! // Opération sur le pool de sémaphores
>   int semop(int semId, struct sembuf *sops, int nsops)
>   {
> !     // Recherche de l'adresse du pool
> !     int32* Address;
>          area_info info;
>       long i;
>
> ! //    printf("semop id : %d n: %d\n",semId,sops->sem_op);
>       get_area_info(semId,&info);
>       Address=(int32*)info.address;
>       if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR))
>       {
>           errno=EINVAL;
>           return -1;
>       }
>
> !     // Execution de l'action
>       for(i=0;i<nsops;i++)
>       {
> !
> ! //        printf("semid %d, n %d\n",Address[sops[i].sem_num+1],sops[i].sem_op);
>           if (sops[i].sem_op < 0)
>           {
> !             acquire_sem_etc(Address[sops[i].sem_num+1],-sops[i].sem_op,0,0);
>           }
>           if (sops[i].sem_op > 0)
>           {
> --- 195,237 ----
>                   }
>               }
>
>               return parea;
>           }
>           else
>           {
> !             /* Area does not exist and no creation is requested */
>               errno=ENOENT;
>               return -1;
>           }
>       }
>   }
>
> ! /* Acquire or release in the semaphore pool */
>   int semop(int semId, struct sembuf *sops, int nsops)
>   {
> !     int32* Address; /*Pool address*/
>          area_info info;
>       long i;
>
> !     /* Get the pool address (semId IS an area id) */
>       get_area_info(semId,&info);
>       Address=(int32*)info.address;
> +
> +     /* Check the validity of semId (it should be an area id) */
>       if ((semId==B_BAD_VALUE)||(semId==B_NO_MEMORY)||(semId==B_ERROR))
>       {
>           errno=EINVAL;
>           return -1;
>       }
>
> !     /* Perform acquire or release */
>       for(i=0;i<nsops;i++)
>       {
> !         /* For each sem in the pool, check the operation to perform */
>           if (sops[i].sem_op < 0)
>           {
> !             /* Try acuiring the semaphore till we are not inteerupted by a signal */
> !             while (acquire_sem_etc(Address[sops[i].sem_num+1],-sops[i].sem_op,0,0)==B_INTERRUPTED);
>           }
>           if (sops[i].sem_op > 0)
>           {
> *** ./src/backend/port/beos/shm.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/shm.c    Tue Oct 10 23:18:00 2000
> ***************
> *** 12,37 ****
>   #include <stdio.h>
>   #include <OS.h>
>
> ! // Detachement d'une zone de mémoire partagée
> ! // On detruit le clone de l'area dans notre adress-space
>   int shmdt(char* shmaddr)
>   {
> !     // Recherche de l'id de l'area présente à cette adresse
>       area_id s;
>       s=area_for(shmaddr);
> ! //    printf("detach area %d\n",s);
> !
> !     // Suppression de l'area
>       return delete_area(s);
>   }
>
> ! // Attachement à une zone de mémoire partagée
> ! // L'area doit bien partie de notre adress-space et on retourne directement l'adress
>   int* shmat(int memId,int m1,int m2)
>   {
> ! //    printf("shmat %d %d %d\n",memId,m1,m2);
> !
> !     // Lecture de notre team_id
>       thread_info thinfo;
>       team_info teinfo;
>       area_info ainfo;
> --- 12,36 ----
>   #include <stdio.h>
>   #include <OS.h>
>
> ! /* Emulating SYS shared memory with beos areas. WARNING : fork clone
> ! areas in copy on write mode */
> !
> !
> ! /* Detach from a shared mem area based on its address */
>   int shmdt(char* shmaddr)
>   {
> !     /* Find area id for this address */
>       area_id s;
>       s=area_for(shmaddr);
> !
> !     /* Delete area */
>       return delete_area(s);
>   }
>
> ! /* Attach to an existing area */
>   int* shmat(int memId,int m1,int m2)
>   {
> !     /* Get our team id */
>       thread_info thinfo;
>       team_info teinfo;
>       area_info ainfo;
> ***************
> *** 39,112 ****
>       get_thread_info(find_thread(NULL),&thinfo);
>       get_team_info(thinfo.team,&teinfo);
>
> !     // Lecture du teamid de l'area
>       if (get_area_info(memId,&ainfo)!=B_OK)
>           printf("AREA %d Invalide\n",memId);
>
>       if (ainfo.team==teinfo.team)
>       {
> !         //retour de l'adresse
> ! //        printf("attach area %d add %d\n",memId,ainfo.address);
>           return (int*)ainfo.address;
>       }
>       else
>       {
> !         // Clone de l'area
>           area_id narea;
>           narea = clone_area(ainfo.name,&(ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId);
>           get_area_info(narea,&ainfo);
> - //        printf("attach area %d in %d add %d\n",memId,narea,ainfo.address);
>           return (int*)ainfo.address;
>       }
>   }
>
> ! // Utilisé uniquement pour supprimer une zone de mémoire partagée
> ! // On fait la meme chose que le detach mais avec un id direct
>   int shmctl(int shmid,int flag, struct shmid_ds* dummy)
>   {
> ! //    printf("shmctl %d %d \n",shmid,flag);
>       delete_area(shmid);
>       return 0;
>   }
>
> ! // Recupération d'une area en fonction de sa référence
> ! // L'area source est identifiée par son nom (convention à moi : SYSV_IPC_SHM : "memId)
>   int shmget(int memKey,int size,int flag)
>   {
> -     int32 n_size;
>       char nom[50];
> -     area_id parea;
>       void* Address;
> !     area_id a;
> !
> !     n_size=((size/4096)+1)*4096;
> !
> ! //    printf("shmget %d %d %d %d\n",memKey,size,flag,nsize);
>
> !     // Determination du nom que doit avoir l'area
>       sprintf(nom,"SYSV_IPC_SHM : %d",memKey);
>
> !
> !     // Recherche de cette area
>       parea=find_area(nom);
>
> !     // L'area existe
>       if (parea!=B_NAME_NOT_FOUND)
>       {
> - //        printf("area found\n");
>           return parea;
>       }
>
> !     // L'area n'existe pas et on n'en demande pas la création : erreur
>       if (flag==0)
>       {
> - //        printf("area %s not found\n",nom);
>           return -1;
>       }
>
> !     // L'area n'existe pas mais on demande sa création
> !     a=create_area(nom,&Address,B_ANY_ADDRESS,n_size,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
> ! //    printf("area %s : %d created addresse %d\n",nom,a,Address);
> !     return a;
>   }
>
> --- 38,96 ----
>       get_thread_info(find_thread(NULL),&thinfo);
>       get_team_info(thinfo.team,&teinfo);
>
> !     /* Get area teamid */
>       if (get_area_info(memId,&ainfo)!=B_OK)
>           printf("AREA %d Invalide\n",memId);
>
>       if (ainfo.team==teinfo.team)
>       {
> !         /* the area is already in our address space, just return the address */
>           return (int*)ainfo.address;
>       }
>       else
>       {
> !         /* the area is not in our address space, clone it before and return the address */
>           area_id narea;
>           narea = clone_area(ainfo.name,&(ainfo.address),B_CLONE_ADDRESS,B_READ_AREA | B_WRITE_AREA,memId);
>           get_area_info(narea,&ainfo);
>           return (int*)ainfo.address;
>       }
>   }
>
> ! /* Control a shared mem area : Used only to delete it */
>   int shmctl(int shmid,int flag, struct shmid_ds* dummy)
>   {
> !     /* Delete the area */
>       delete_area(shmid);
>       return 0;
>   }
>
> ! /* Get an area based on the IPC key */
>   int shmget(int memKey,int size,int flag)
>   {
>       char nom[50];
>       void* Address;
> !     area_id parea;
>
> !     /* Area name */
>       sprintf(nom,"SYSV_IPC_SHM : %d",memKey);
>
> !     /* Find area */
>       parea=find_area(nom);
>
> !     /* area exist, just return its id */
>       if (parea!=B_NAME_NOT_FOUND)
>       {
>           return parea;
>       }
>
> !     /* area does not exist and no creation is requested : error */
>       if (flag==0)
>       {
>           return -1;
>       }
>
> !     /* area does not exist and its creation is requested, create it (be sure to have a 4ko multiple size */
> !     return create_area(nom,&Address,B_ANY_ADDRESS,((size/4096)+1)*4096,B_NO_LOCK,B_READ_AREA | B_WRITE_AREA);
 
>   }
>
> *** ./src/backend/port/beos/support.c.orig    Sat Oct 28 18:27:40 2000
> --- ./src/backend/port/beos/support.c    Sun Oct 15 23:30:35 2000
> ***************
> *** 11,57 ****
>   #include "postgres.h"
>
>   /* Support Globals */
> - char* self_binary=NULL;
>   port_id beos_dl_port_in=0;
>   port_id beos_dl_port_out=0;
>   sem_id beos_shm_sem;
>
>   image_id beos_dl_open(char * filename)
>   {
>       image_id im;
>
> !     /* Start the support server */
> !     if (self_binary==NULL)
> !     {
> !         /* Can't start support server without binary name */
> !         elog(NOTICE, "Error loading BeOS support server : can't find binary");
> !         return B_ERROR;
> !     }
> !     else
>       {
> !         /* If a port doesn't exist, lauch support server */
>           if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>           {
> !             /* Create communication port */
> !             beos_dl_port_in=create_port(50,"beos_support_in");
> !             beos_dl_port_out=create_port(50,"beos_support_in");
> !
>
> !             if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
> !             {
> !                 elog(NOTICE, "Error loading BeOS support server : can't create communication ports");
 
> !                 return B_ERROR;
> !             }
> !             else
> !             {
> !                 char Cmd[4000];
> !
> !                 /* Build arg list */
> !                 sprintf(Cmd,"%s -beossupportserver %d %d
&",self_binary,(int)beos_dl_port_in,(int)beos_dl_port_out);
> !
> !                 /* Lauch process */
> !                 system(Cmd);
> !             }
>           }
>       }
>
> --- 11,58 ----
>   #include "postgres.h"
>
>   /* Support Globals */
>   port_id beos_dl_port_in=0;
>   port_id beos_dl_port_out=0;
>   sem_id beos_shm_sem;
>
> + /* Global var containing the postgres path */
> + extern char        pg_pathname[];
> +
> +
> + /* Shared library loading doesn't work after fork in beos. The solution is to use an exact
> + copy of the process and use it to perform the loading, then just map the Text and Data segment
> + of the add-on in our address space. Both process must have the exact same memory mapping, so
> + we use the postgres executable. When it's lauched with the -beossupportserver parameter, the
> + postgres executable just run a loop to wait command on a port. Its only action is to load the addon,
> + the beos_dl_open will then remap the good areas in the backend address space. */
> +
> +
>   image_id beos_dl_open(char * filename)
>   {
>       image_id im;
>
> !     /* If a port doesn't exist, lauch support server */
> !     if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>       {
> !         /* Create communication port */
> !         beos_dl_port_in=create_port(50,"beos_support_in");
> !         beos_dl_port_out=create_port(50,"beos_support_in");
> !
> !
>           if ((beos_dl_port_in<=0)||(beos_dl_port_out<=0))
>           {
> !             elog(NOTICE, "Error loading BeOS support server : can't create communication ports");
> !             return B_ERROR;
> !         }
> !         else
> !         {
> !             char Cmd[4000];
> !
> !             /* Build arg list */
> !             sprintf(Cmd,"%s -beossupportserver %d %d &",pg_pathname,(int)beos_dl_port_in,(int)beos_dl_port_out);
>
> !             /* Lauch process */
> !             system(Cmd);
>           }
>       }
>
> ***************
> *** 132,143 ****
>   {
>       if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))
>       {
> !         /* Shared memory cloning protection semaphore */
>           beos_shm_sem=create_sem(1,"beos_shm_sem");
>       }
>
>       if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
>       {
>           port_id port_in;
>           port_id port_out;
>
> --- 133,146 ----
>   {
>       if (strlen(argv[0]) >= 10 && !strcmp(argv[0] + strlen(argv[0]) - 10, "postmaster"))
>       {
> !         /* We are in the postmaster, create the protection semaphore for shared mem remapping */
>           beos_shm_sem=create_sem(1,"beos_shm_sem");
>       }
>
>       if (argc > 1 && strcmp(argv[1], "-beossupportserver") == 0)
>       {
> +         /* We are in the support server, run it ... */
> +
>           port_id port_in;
>           port_id port_out;
>
> ***************
> *** 211,258 ****
>   }
>
>
> ! void beos_backend_startup(char * binary)
>   {
> -     team_id ct;
> -     thread_info inft;
>       char nom[50];
>       char nvnom[50];
>       area_info inf;
>       int32 cook=0;
>
> !     /* remember full path binary name to load dl*/
> !     self_binary=strdup(binary);
>
> !     /* find the current team */
> !     get_thread_info(find_thread(NULL),&inft);
> !     ct=inft.team;
> !
> !     /* find all area with a name begining by pgsql and destroy / clone then */
> !
> !     /* This operation must be done by only one backend at a time */
> !     if(acquire_sem(beos_shm_sem)==B_OK)
>       {
> !         while (get_next_area_info(0, &cook, &inf) == B_OK)
>           {
> !             strcpy(nom,inf.name);
> !             strcpy(nvnom,inf.name);
> !             nom[9]=0;
> !             nvnom[5]='i';
> !             if (!strcmp(nom,"SYSV_IPC_"))
> !             {
> !                 void* add;
> !                 area_id ar;
> !                 add=inf.address;
> !                 delete_area(inf.area);
> !                 ar=find_area(inf.name);
> !                 clone_area(nvnom,&add,B_CLONE_ADDRESS,B_READ_AREA|B_WRITE_AREA,ar);
> !             }
> !         }
> !         release_sem(beos_shm_sem);
> !     }
> !     else
> !     {
> !         /* Fatal error, exiting with error */
> !         exit(1);
> !     }
>   }
> --- 214,290 ----
>   }
>
>
> !
> ! /* The behavior of fork is borken on beos regarding shared memory. In fact
> ! all shared memory areas are clones in copy on write mode in the new process.
> !
> ! We need to do a remapping of these areas. Just afer the fork we performe the
> ! following actions :
> !
> !     * Find all areas with a name begining by SYS_V_IPC_ in our process
> !     (areas created by the SYSV IPC emulation functions). The name is
> !     followed by the IPC KEY in decimal format
> !
> !     * For each area we do :
> !
> !         * 1 : Get its name
> !         * 2 : destroy it
> !         * 3 : find another area with the exact same name
> !         * 4 : clone it in our address space with a different name
> !
> !     There is a race condition in 3-4 : if there two fork in a very short
> !     time, in step 3 we might end up with two areas with the same name, and no
> !     possibility to find the postmaster one. So the whole process is protected
> !     by a semaphore which is acquires just before the fork and released in case
> !     of fork failure or just after the end of the remapping.*/
> !
> ! void beos_before_backend_startup(void)
> ! {
> !     /* Just before forking, acquire the semaphore */
> !     if(acquire_sem(beos_shm_sem)!=B_OK)
> !         exit(1);         /* Fatal error, exiting with error */
> ! }
> !
> ! void beos_backend_startup_failed(void)
> ! {
> !     /* The foek failed, just release the semaphore */
> !     release_sem(beos_shm_sem);
> ! }
> !
> !
> ! void beos_backend_startup(void)
>   {
>       char nom[50];
>       char nvnom[50];
>       area_info inf;
>       int32 cook=0;
>
> !     /* Perform the remapping process */
>
> !     /* Loop in all our team areas */
> !     while (get_next_area_info(0, &cook, &inf) == B_OK)
>       {
> !         strcpy(nom,inf.name);
> !         strcpy(nvnom,inf.name);
> !         nom[9]=0;
> !         nvnom[5]='i';
> !         /* Is it a SYS V area ? */
> !         if (!strcmp(nom,"SYSV_IPC_"))
>           {
> !             void* area_address;
> !             area_id area_postmaster;
> !             /* Get the area address */
> !             area_address=inf.address;
> !             /* Destroy the bad area */
> !             delete_area(inf.area);
> !             /* Find the postmaster area */
> !             area_postmaster=find_area(inf.name);
> !             /* Clone it at the exact same address */
> !             clone_area(nvnom,&area_address,B_CLONE_ADDRESS,B_READ_AREA|B_WRITE_AREA,area_postmaster);
> !         }
> !     }
> !
> !     /* remapping done release semaphore to allow other backend to startup */
> !
> !     release_sem(beos_shm_sem);
>   }
> *** ./src/backend/postmaster/postmaster.c.orig    Sat Oct 28 01:42:23 2000
> --- ./src/backend/postmaster/postmaster.c    Sat Oct 28 01:43:53 2000
> ***************
> *** 1719,1726 ****
> --- 1719,1734 ----
>       fflush(stdout);
>       fflush(stderr);
>
> + #ifdef __BEOS__
> +     /* Specific beos actions before backend startup */
> +     beos_before_backend_startup();
> + #endif
>       if ((pid = fork()) == 0)
>       {                            /* child */
> + #ifdef __BEOS__
> +         /* Specific beos backend stratup actions */
> +         beos_backend_startup();
> + #endif
>           if (DoBackend(port))
>           {
>               fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n",
> ***************
> *** 1734,1739 ****
> --- 1742,1751 ----
>       /* in parent */
>       if (pid < 0)
>       {
> + #ifdef __BEOS__
> +         /* Specific beos backend stratup actions */
> +         beos_backend_startup_failed();
> + #endif
>           fprintf(stderr, "%s: BackendStartup: fork failed: %s\n",
>                   progname, strerror(errno));
>           return STATUS_ERROR;
> *** ./src/backend/tcop/postgres.c.orig    Sat Oct 28 18:31:06 2000
> --- ./src/backend/tcop/postgres.c    Sat Oct 28 18:31:30 2000
> ***************
> *** 1480,1490 ****
>
>       if (IsUnderPostmaster)
>       {
> - #ifdef __BEOS__
> -         /* Specific beos backend stratup actions */
> -         beos_backend_startup(argv[0]);
> - #endif
> -
>           /* noninteractive case: nothing should be left after switches */
>           if (errs || argc != optind || DBName == NULL)
>           {
> --- 1480,1485 ----
> *** ./src/include/port/beos.h.orig    Sat Oct 28 18:28:38 2000
> --- ./src/include/port/beos.h    Sat Oct 28 02:02:17 2000
> ***************
> *** 1,4 ****
> --- 1,6 ----
>   #include <kernel/OS.h>
> + #include "kernel/image.h"
> +
>   #define USE_POSIX_TIME
>   #define HAS_TEST_AND_SET
>
> ***************
> *** 6,73 ****
>
>   #define AF_UNIX     1 /* no domain sockets on BeOS */
>
> ! #ifdef __cplusplus
> ! extern "C" {
> ! #endif
> !     #include "kernel/image.h"
> !
> !     #undef HAVE_UNION_SEMUN
> !     #define HAVE_UNION_SEMUN 1
> !     #undef HAVE_SYS_SEM_H
> !     #undef HAVE_SYS_SHM_H
> !
> !     union semun
> !     {
> !         int            val;
> !         struct semid_ds *buf;
> !         unsigned short *array;
> !     };
> !     /* SYS V emulation */
> !
> !     #define IPC_RMID 256
> !     #define IPC_CREAT 512
> !     #define IPC_EXCL 1024
> !     #define IPC_PRIVATE 234564
> !
> !     #define EACCESS 2048
> !     #define EIDRM 4096
> !
> !     #define SETALL 8192
> !     #define GETNCNT 16384
> !     #define GETVAL 65536
> !     #define SETVAL 131072
> !
> !     struct sembuf
> !     {
> !         int sem_flg;
> !         int sem_op;
> !         int sem_num;
> !     };
> !
> !     int semctl(int semId,int semNum,int flag,union semun);
> !     int semget(int semKey, int semNum, int flags);
> !     int semop(int semId, struct sembuf *sops, int flag);
> !
> !     struct shmid_ds
> !     {
> !         int            dummy;
> !     };
>
> !     int shmdt(char* shmaddr);
> !     int* shmat(int memId,int m1,int m2);
> !     int shmctl(int shmid,int flag, struct shmid_ds* dummy);
> !     int shmget(int memKey,int size,int flag);
> !
> !
> !     /* Support functions */
> !     /* Specific beos action made on postgres/postmaster startup */
> !     void beos_startup(int argc,char** argv);
> !     /* Load a shared library */
> !     image_id beos_dl_open(char * filename);
> !     /* UnLoad a shared library */
> !     status_t beos_dl_close(image_id im);
> !     /* Specific beos action made on backend startup */
> !     void beos_backend_startup(char* binary);
> ! #ifdef __cplusplus
> ! }
> ! #endif
> \ No newline at end of file
> --- 8,71 ----
>
>   #define AF_UNIX     1 /* no domain sockets on BeOS */
>
> ! /* SYS V emulation */
> !
> ! #undef HAVE_UNION_SEMUN
> ! #define HAVE_UNION_SEMUN 1
> !
> ! #define IPC_RMID 256
> ! #define IPC_CREAT 512
> ! #define IPC_EXCL 1024
> ! #define IPC_PRIVATE 234564
> !
> ! #define EACCESS 2048
> ! #define EIDRM 4096
> !
> ! #define SETALL 8192
> ! #define GETNCNT 16384
> ! #define GETVAL 65536
> ! #define SETVAL 131072
> !
> ! union semun
> ! {
> !     int            val;
> !     struct semid_ds *buf;
> !     unsigned short *array;
> ! };
> !
> ! struct sembuf
> ! {
> !     int sem_flg;
> !     int sem_op;
> !     int sem_num;
> ! };
> !
> ! struct shmid_ds
> ! {
> !     int            dummy;
> ! };
>
> ! int semctl(int semId,int semNum,int flag,union semun);
> ! int semget(int semKey, int semNum, int flags);
> ! int semop(int semId, struct sembuf *sops, int flag);
> !
> ! int shmdt(char* shmaddr);
> ! int* shmat(int memId,int m1,int m2);
> ! int shmctl(int shmid,int flag, struct shmid_ds* dummy);
> ! int shmget(int memKey,int size,int flag);
> !
> !
> ! /* Support functions */
> !
> ! /* Specific beos action made on postgres/postmaster startup */
> ! void beos_startup(int argc,char** argv);
> ! /* Load a shared library */
> ! image_id beos_dl_open(char * filename);
> ! /* UnLoad a shared library */
> ! status_t beos_dl_close(image_id im);
> ! /* Specific beos action made on backend startup */
> ! void beos_before_backend_startup(void);
> ! /* Specific beos action made on backend startup */
> ! void beos_backend_startup(void);
> ! /* Specific beos action made on backend startup failure*/
> ! void beos_backend_startup_failed(void);
>
[ application/x-be_attribute is not supported, skipping... ]


--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 853-3000
  +  If your life is a hard drive,     |  830 Blythe Avenue
  +  Christ can be your backup.        |  Drexel Hill, Pennsylvania 19026


pgsql-patches by date:

Previous
From: Pete Forman
Date:
Subject: Re: Improved fix for sys_nerr
Next
From: The Hermit Hacker
Date:
Subject: and, finally ... pgsql-patches should be live once more ...