Re: Beos updates

Started by Bruce Momjianover 25 years ago1 messagespatches
Jump to latest
#1Bruce Momjian
bruce@momjian.us

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