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