mirror of https://github.com/postgres/postgres
parent
6f84b2da75
commit
44f9021223
@ -1,30 +0,0 @@ |
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Makefile--
|
||||
# Makefile for port/beos
|
||||
#
|
||||
# IDENTIFICATION
|
||||
# $PostgreSQL: pgsql/src/backend/port/beos/Makefile,v 1.4 2003/11/29 19:51:54 pgsql Exp $
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
subdir = src/backend/port/beos
|
||||
top_builddir = ../../../..
|
||||
include $(top_builddir)/src/Makefile.global |
||||
|
||||
OBJS = sem.o shm.o support.o
|
||||
|
||||
all: SUBSYS.o |
||||
|
||||
SUBSYS.o: $(OBJS) |
||||
$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
|
||||
|
||||
depend dep: |
||||
$(CC) -MM $(CFLAGS) $(CPPFLAGS) *.c >depend
|
||||
|
||||
clean: |
||||
rm -f SUBSYS.o $(OBJS)
|
||||
|
||||
ifeq (depend,$(wildcard depend)) |
||||
include depend |
||||
endif |
@ -1,312 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* sem.c |
||||
* BeOS System V Semaphores Emulation |
||||
* |
||||
* Copyright (c) 1999-2000, Cyril VELTER |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#include "postgres.h" |
||||
|
||||
#include <errno.h> |
||||
#include <unistd.h> |
||||
#include <OS.h> |
||||
|
||||
/*#define TDBG*/ |
||||
#ifdef TDBG |
||||
#define TRACEDBG(x) printf(x);printf("\n") |
||||
#define TRACEDBGP(x,y) printf(x,y);printf("\n") |
||||
#define TRACEDBGPP(x,y,z) printf(x,y,z);printf("\n") |
||||
#else |
||||
#define TRACEDBG(x) |
||||
#define TRACEDBGP(x,y) |
||||
#define TRACEDBGPP(x,y,z) |
||||
#endif |
||||
|
||||
/* 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; |
||||
|
||||
TRACEDBG("->semctl"); |
||||
/* Try to find the pool */ |
||||
if (get_area_info(semId, &info) != B_OK) |
||||
{ |
||||
/* pool is invalid (BeOS area id is invalid) */ |
||||
errno = EINVAL; |
||||
TRACEDBG("<-semctl invalid pool"); |
||||
return -1; |
||||
} |
||||
|
||||
/* Get the pool address */ |
||||
Address = (int32 *) info.address; |
||||
TRACEDBGP("--semctl address %d", 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; |
||||
|
||||
TRACEDBG("--semctl setall"); |
||||
for (i = 0; i < Address[0]; i++) |
||||
{ |
||||
int32 cnt; |
||||
|
||||
/* Get the current count */ |
||||
get_sem_count(Address[2 * i + 1], &cnt); |
||||
|
||||
TRACEDBGP("--semctl setall %d", semun.array[i]); |
||||
|
||||
/* Compute and set the new count (relative to the old one) */ |
||||
cnt -= semun.array[i]; |
||||
TRACEDBGPP("--semctl acquire id : %d cnt : %d", Address[2 * i + 1], cnt); |
||||
if (cnt > 0) |
||||
while (acquire_sem_etc(Address[2 * i + 1], cnt, 0, 0) == B_INTERRUPTED); |
||||
if (cnt < 0) |
||||
release_sem_etc(Address[2 * i + 1], -cnt, 0); |
||||
} |
||||
return 1; |
||||
} |
||||
|
||||
/* Fix the count of one semaphore to semun.val */ |
||||
if (flag == SETVAL) |
||||
{ |
||||
int32 cnt; |
||||
|
||||
TRACEDBGP("--semctl setval %d", semun.val); |
||||
/* Get the current count */ |
||||
get_sem_count(Address[2 * semNum + 1], &cnt); |
||||
|
||||
/* Compute and set the new count (relative to the old one) */ |
||||
cnt -= semun.val; |
||||
TRACEDBGPP("--semctl acquire id : %d cnt : %d", Address[2 * semNum + 1], cnt); |
||||
if (cnt > 0) |
||||
while (acquire_sem_etc(Address[2 * semNum + 1], cnt, 0, 0) == B_INTERRUPTED); |
||||
if (cnt < 0) |
||||
release_sem_etc(Address[2 * semNum + 1], -cnt, 0); |
||||
return 1; |
||||
} |
||||
|
||||
/* Get the last pid which accessed the sem */ |
||||
if (flag == GETPID) |
||||
{ |
||||
TRACEDBG("->semctl getpid"); |
||||
return Address[2 * semNum + 2]; |
||||
} |
||||
|
||||
/* Delete the pool */ |
||||
if (flag == IPC_RMID) |
||||
{ |
||||
long i; |
||||
|
||||
thread_info ti; |
||||
|
||||
TRACEDBG("->semctl rmid"); |
||||
get_thread_info(find_thread(NULL), &ti); |
||||
|
||||
/* Loop over all semaphore to delete them */ |
||||
TRACEDBGP("->semctl nmbre %d", Address[0]); |
||||
for (i = 0; i < Address[0]; i++) |
||||
{ |
||||
/*
|
||||
* Make sure to have ownership of the semaphore (if created by |
||||
* another team) |
||||
*/ |
||||
TRACEDBGP("->semctl id %d", Address[2 * i + 1]); |
||||
set_sem_owner(Address[2 * i + 1], ti.team); |
||||
|
||||
/* Delete the semaphore */ |
||||
delete_sem(Address[2 * i + 1]); |
||||
|
||||
/*
|
||||
* Reset to an invalid semId (in case other process try to get the |
||||
* infos from a cloned area |
||||
*/ |
||||
Address[2 * 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 */ |
||||
TRACEDBG("--semctl getncnt"); |
||||
elog(ERROR, "semctl error: GETNCNT not implemented"); |
||||
return 0; |
||||
} |
||||
|
||||
/* Get the current semaphore count of the first semaphore in the pool */ |
||||
if (flag == GETVAL) |
||||
{ |
||||
int32 cnt; |
||||
|
||||
TRACEDBG("--semctl getval"); |
||||
get_sem_count(Address[2 * semNum + 1], &cnt); |
||||
TRACEDBGP("--semctl val %d", cnt); |
||||
return cnt; |
||||
} |
||||
|
||||
elog(ERROR, "semctl error: unknown flag"); |
||||
|
||||
TRACEDBG("<-semctl 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; |
||||
|
||||
TRACEDBGPP("->semget key : %d num : %d", semKey, semNum); |
||||
/* Name of the area to find */ |
||||
sprintf(Nom, "SYSV_IPC_SEM : %d", semKey); |
||||
|
||||
/* find area */ |
||||
parea = find_area(Nom); |
||||
|
||||
/* Test of area existence */ |
||||
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 250 (8 byte per sem : 4 for the semid and 4 for the |
||||
* last pid which accessed the semaphore in a pool |
||||
*/ |
||||
if (semNum > 250) |
||||
{ |
||||
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 = 0; i < Address[0]; i++) |
||||
{ |
||||
/* Create the semaphores */ |
||||
Address[2 * i + 1] = create_sem(0, Nom); |
||||
|
||||
if ((Address[2 * i + 1] == B_BAD_VALUE) || (Address[2 * i + 1] == B_NO_MEMORY) || (Address[2 * i + 1] == B_NO_MORE_SEMS)) |
||||
{ |
||||
errno = ENOMEM; |
||||
return -1; |
||||
} |
||||
} |
||||
|
||||
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; |
||||
long ret; |
||||
|
||||
/* 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++) |
||||
{ |
||||
/* remember the PID */ |
||||
Address[2 * (sops[i].sem_num) + 2] = getpid(); |
||||
|
||||
/* For each sem in the pool, check the operation to perform */ |
||||
if (sops[i].sem_op < 0) |
||||
{ |
||||
/*
|
||||
* Try acquiring the semaphore till we are not interrupted by a |
||||
* signal |
||||
*/ |
||||
if (sops[i].sem_flg == IPC_NOWAIT) |
||||
{ |
||||
/* Try to lock ... */ |
||||
while ((ret = acquire_sem_etc(Address[2 * (sops[i].sem_num) + 1], -sops[i].sem_op, B_RELATIVE_TIMEOUT, 0)) == B_INTERRUPTED); |
||||
if (ret != B_OK) |
||||
return EWOULDBLOCK; |
||||
} |
||||
else |
||||
while (acquire_sem_etc(Address[2 * (sops[i].sem_num) + 1], -sops[i].sem_op, 0, 0) == B_INTERRUPTED); |
||||
} |
||||
if (sops[i].sem_op > 0) |
||||
release_sem_etc(Address[2 * (sops[i].sem_num) + 1], sops[i].sem_op, 0); |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -1,137 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* shm.c |
||||
* BeOS System V Shared Memory Emulation |
||||
* |
||||
* Copyright (c) 1999-2001, Cyril VELTER |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#include "postgres.h" |
||||
#include <OS.h> |
||||
#include <errno.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; |
||||
|
||||
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); |
||||
} |
@ -1,344 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* support.c |
||||
* BeOS Support functions |
||||
* |
||||
* Copyright (c) 1999-2001, Cyril VELTER |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#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 my_exec_path[]; |
||||
|
||||
|
||||
/* 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(WARNING, "error loading BeOS support server: could not create communication ports"); |
||||
return B_ERROR; |
||||
} |
||||
else |
||||
{ |
||||
char Cmd[4000]; |
||||
|
||||
/* Build arg list */ |
||||
sprintf(Cmd, "%s -beossupportserver %d %d &", my_exec_path, (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(WARNING, "could not 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(WARNING, "could not 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(WARNING, "could not load this add-on: map data error"); |
||||
} |
||||
|
||||
return im; |
||||
} |
||||
} |
||||
|
||||
void |
||||
beos_dl_sym(image_id im, char *symname, void **fptr) |
||||
{ |
||||
/* Send command '3' (get symbol) to the support server */ |
||||
write_port(beos_dl_port_in, 3, symname, strlen(symname) + 1); |
||||
write_port(beos_dl_port_in, im, NULL, 0); |
||||
|
||||
/* Read sym address */ |
||||
read_port(beos_dl_port_out, (int32 *) (fptr), NULL, 0); |
||||
|
||||
if (fptr == NULL) |
||||
elog(WARNING, "loading symbol \"%s\" failed", symname); |
||||
} |
||||
|
||||
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")) |
||||
{ |
||||
/*
|
||||
* 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; |
||||
|
||||
/* 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; |
||||
void *fpt; |
||||
|
||||
/* 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 */ |
||||
case 3: |
||||
|
||||
/* read image Id on the input port */ |
||||
read_port(port_in, &addon, NULL, 0); |
||||
|
||||
/* Loading symbol */ |
||||
fpt = NULL; |
||||
|
||||
|
||||
if (get_image_symbol(addon, datas, B_SYMBOL_TYPE_TEXT, &fpt) == B_OK); |
||||
{ |
||||
/*
|
||||
* Sometime the loader return B_OK for an inexistant |
||||
* function with an invalid address !!! Check that the |
||||
* return address is in the image range |
||||
*/ |
||||
|
||||
get_image_info(addon, &info_im); |
||||
if ((fpt < info_im.text) ||(fpt >= (info_im.text +info_im.text_size))) |
||||
fpt = NULL; |
||||
} |
||||
|
||||
/* Send back fptr of data segment */ |
||||
write_port(port_out, (int32) (fpt), NULL, 0); |
||||
break; |
||||
|
||||
default: |
||||
/* Free system resources */ |
||||
delete_port(port_in); |
||||
delete_port(port_out); |
||||
/* Exit */ |
||||
exit(0); |
||||
break; |
||||
} |
||||
} |
||||
/* Never be there */ |
||||
exit(1); |
||||
} |
||||
} |
||||
|
||||
|
||||
|
||||
/* The behavior of fork is broken 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 fork 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); |
||||
/* Compute new area name */ |
||||
sprintf(nvnom, "SYSV_IPC %d", area_postmaster); |
||||
/* 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); |
||||
} |
@ -1,69 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* dynloader.c |
||||
* Dynamic Loader for Postgres for BeOS |
||||
* |
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* |
||||
* IDENTIFICATION |
||||
* $PostgreSQL: pgsql/src/backend/port/dynloader/beos.c,v 1.15 2004/12/31 22:00:32 pgsql Exp $ |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
|
||||
#include "postgres.h" |
||||
|
||||
#include "utils/dynamic_loader.h" |
||||
|
||||
|
||||
void * |
||||
pg_dlopen(char *filename) |
||||
{ |
||||
image_id *im; |
||||
|
||||
/* Handle memory allocation to store the Id of the shared object */ |
||||
im = (image_id *) (malloc(sizeof(image_id))); |
||||
|
||||
/* Add-on loading */ |
||||
*im = beos_dl_open(filename); |
||||
|
||||
return im; |
||||
} |
||||
|
||||
|
||||
char * |
||||
pg_dlerror() |
||||
{ |
||||
static char errmsg[] = "Load Add-On failed"; |
||||
|
||||
return errmsg; |
||||
} |
||||
|
||||
PGFunction |
||||
pg_dlsym(void *handle, char *funcname) |
||||
{ |
||||
PGFunction fpt; |
||||
|
||||
/* Checking that "Handle" is valid */ |
||||
if ((handle) && ((*(int *) (handle)) >= 0)) |
||||
{ |
||||
beos_dl_sym(*((int *) (handle)), funcname, (void **) &fpt); |
||||
return fpt; |
||||
} |
||||
elog(WARNING, "add-on not loaded correctly"); |
||||
return NULL; |
||||
} |
||||
|
||||
void |
||||
pg_dlclose(void *handle) |
||||
{ |
||||
/* Checking that "Handle" is valid */ |
||||
if ((handle) && ((*(int *) (handle)) >= 0)) |
||||
{ |
||||
if (beos_dl_close(*(image_id *) handle) != B_OK) |
||||
elog(WARNING, "error while unloading add-on"); |
||||
free(handle); |
||||
} |
||||
} |
@ -1,17 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* port_protos.h |
||||
* port-specific prototypes for BeOS |
||||
* |
||||
* |
||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* $PostgreSQL: pgsql/src/backend/port/dynloader/beos.h,v 1.11 2004/12/31 22:00:32 pgsql Exp $ |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#ifndef PORT_PROTOS_H |
||||
#define PORT_PROTOS_H |
||||
|
||||
#endif /* PORT_PROTOS_H */ |
@ -1,82 +0,0 @@ |
||||
#include <kernel/OS.h> |
||||
#include <kernel/image.h> |
||||
#include <sys/ioctl.h> |
||||
|
||||
#define AF_UNIX 10 /* no domain sockets on BeOS */ |
||||
|
||||
/* Beos doesn't have all the required getrusage fields */ |
||||
#undef HAVE_GETRUSAGE |
||||
|
||||
/* 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 IPC_NOWAIT 2048 |
||||
#define IPC_STAT 4096 |
||||
|
||||
#define EACCESS 2048 |
||||
#define EIDRM 4096 |
||||
|
||||
#define SETALL 8192 |
||||
#define GETNCNT 16384 |
||||
#define GETVAL 65536 |
||||
#define SETVAL 131072 |
||||
#define GETPID 262144 |
||||
|
||||
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 shm_nattch; |
||||
}; |
||||
|
||||
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); |
||||
|
||||
/* Find symbol */ |
||||
void beos_dl_sym(image_id im, char *symname, void **fptr); |
||||
|
||||
/* 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); |
@ -1,19 +0,0 @@ |
||||
MK_NO_LORDER=true
|
||||
AROPT = crs
|
||||
|
||||
ifdef ELF_SYSTEM |
||||
export_dynamic = -Wl,-E
|
||||
endif |
||||
|
||||
DLSUFFIX = .so
|
||||
CFLAGS_SL = -fpic -DPIC
|
||||
|
||||
%.so: %.o |
||||
ifdef PGXS |
||||
ln -fs $(DESTDIR)$(bindir)/postgres _APP_
|
||||
else |
||||
ln -fs $(top_builddir)/src/backend/postgres _APP_
|
||||
endif |
||||
$(CC) -nostart -Xlinker -soname=$@ -o $@ _APP_ $<
|
||||
|
||||
sqlmansect = 7
|
Loading…
Reference in new issue