/*------------------------------------------------------------------------- * * shm.c * BeOS System V Shared Memory Emulation * * Copyright (c) 1999-2001, Cyril VELTER * *------------------------------------------------------------------------- */ #include "postgres.h" #include #include #include /* 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; 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 */ int shmctl(int shmid, int flag, struct shmid_ds* dummy) { if (flag == IPC_RMID) { /* Delete the area */ delete_area(shmid); return 0; } if (flag == IPC_STAT) { /* Find any SYSV area with the shmid in its name */ area_info inf; team_info infteam; int32 cookteam=0; char name[50]; sprintf(name,"SYSV_IPC %d",shmid); dummy->shm_nattch=0; while (get_next_team_info(&cookteam, &infteam) == B_OK) { int32 cook=0; while (get_next_area_info(infteam.team, &cook, &inf) == B_OK) { if (strcmp(name,inf.name) == 0) { dummy->shm_nattch++; } } } errno = 0; return 0; } errno = EINVAL; return -1; } /* 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); }