+ {
+ 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))
+ {
+ errno=ENOMEM;
+ return -1;
+ }
+ }
+
+// 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
+ {
+
+// 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)
+ {
+ release_sem_etc(Address[sops[i].sem_num+1],sops[i].sem_op,0);
+ }
+ }
+ return 0;
+}
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * shm.c
+ * BeOS System V Shared Memory Emulation
+ *
+ * Copyright (c) 1999-2000, Cyril VELTER
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#include "postgres.h"
+#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;
+
+ 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;
+}
+
--- /dev/null
+/*-------------------------------------------------------------------------
+ *
+ * support.c
+ * BeOS Support functions
+ *
+ * Copyright (c) 1999-2000, Cyril VELTER
+ *
+ *-------------------------------------------------------------------------
+ */
+
+#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);
+ }
+ }
+ }
+
+ /* Add-on loading */
+
+ /* Send command '1' (load) to the support server */
+ write_port(beos_dl_port_in,1,filename,strlen(filename)+1);
+
+ /* Read Object Id */
+ read_port(beos_dl_port_out,&im,NULL,0);
+
+ /* Checking integrity */
+ if (im<0)
+ {
+ elog(NOTICE, "Can't load this add-on ");
+ return B_ERROR;
+ }
+ else
+ {
+ /* Map text and data segment in our address space */
+ char datas[4000];
+ int32 area;
+ int32 resu;
+ void* add;
+
+ /* read text segment id and address */
+ read_port(beos_dl_port_out,&area,datas,4000);
+ read_port(beos_dl_port_out,(void*)&add,datas,4000);
+ /* map text segment in our address space */
+ resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+ if (resu<0)
+ {
+ /* If we can't map, we are in reload case */
+ /* delete the mapping */
+ resu=delete_area(area_for(add));
+ /* Remap */
+ resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+ if (resu<0)
+ {
+ elog(NOTICE, "Can't load this add-on : map text error");
+ }
+ }
+
+ /* read text segment id and address */
+ read_port(beos_dl_port_out,&area,datas,4000);
+ read_port(beos_dl_port_out,(void*)&add,datas,4000);
+ /* map text segment in our address space */
+ resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+ if (resu<0)
+ {
+ /* If we can't map, we are in reload case */
+ /* delete the mapping */
+ resu=delete_area(area_for(add));
+ /* Remap */
+ resu=clone_area(datas,&add,B_EXACT_ADDRESS,B_READ_AREA|B_WRITE_AREA,area);
+ if (resu<0)
+ {
+ elog(NOTICE, "Can't load this add-on : map data error");
+ }
+ }
+
+ return im;
+ }
+}
+
+status_t beos_dl_close(image_id im)
+{
+ /* unload add-on */
+ int32 resu;
+ write_port(beos_dl_port_in,2,&im,4);
+ read_port(beos_dl_port_out,&resu,NULL,0);
+ return resu;
+}
+
+/* Main support server loop */
+
+void beos_startup(int argc,char** argv)
+{
+ 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;
+
+ /* Get back port ids from arglist */
+ sscanf(argv[2],"%d",(int*)(&port_in));
+ sscanf(argv[3],"%d",(int*)(&port_out));
+
+ /* Main server loop */
+ for (;;)
+ {
+ int32 opcode=0;
+ char datas[4000];
+
+ /* Wait for a message from the backend :
+ 1 : load a shared object
+ 2 : unload a shared object
+ any other : exit support server */
+ read_port(port_in,&opcode,datas,4000);
+
+ switch(opcode)
+ {
+ image_id addon;
+ image_info info_im;
+ area_info info_ar;
+
+ /* Load Add-On */
+ case 1 :
+
+ /* Load shared object */
+ addon=load_add_on(datas);
+
+ /* send back the shared object Id */
+ write_port(port_out,addon,NULL,0);
+
+ /* Get Shared Object infos */
+ get_image_info(addon,&info_im);
+
+ /* get text segment info */
+ get_area_info(area_for(info_im.text),&info_ar);
+ /* Send back area_id of text segment */
+ write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
+ /* Send back real address of text segment */
+ write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
+
+
+ /* get data segment info */
+ get_area_info(area_for(info_im.data),&info_ar);
+ /* Send back area_id of data segment */
+ write_port(port_out,info_ar.area,info_ar.name,strlen(info_ar.name)+1);
+ /* Send back real address of data segment */
+ write_port(port_out,(int)info_ar.address,info_ar.name,strlen(info_ar.name)+1);
+ break;
+ /* UnLoad Add-On */
+ case 2 :
+ /* Unload shared object and send back the result of the operation */
+ write_port(port_out,unload_add_on(*((int*)(datas))),NULL,0);
+ break;
+ /* Cleanup and exit */
+ default:
+ /* Free system resources */
+ delete_port(port_in);
+ delete_port(port_out);
+ /* Exit */
+ exit(0);
+ break;
+ }
+ }
+ /* Never be there */
+ exit(1);
+ }
+}
+
+
+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);
+ }
+}