From: bonefish@cs.tu-berlin.de Date: Fri, 17 Dec 2004 01:17:40 +0000 (+0100) Subject: Re: [perl #32717] BeOS specific Updates X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e56d2c0452c35b83da9b40ac35fd5558c48f7b73;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #32717] BeOS specific Updates Message-Id: <20041217011740.14398.1@cs.tu-berlin.de> p4raw-id: //depot/perl@23661 --- diff --git a/MANIFEST b/MANIFEST index 3d96603..219da18 100644 --- a/MANIFEST +++ b/MANIFEST @@ -6,8 +6,6 @@ av.c Array value code av.h Array value header beos/beos.c BeOS port beos/beosish.h BeOS port -beos/beos_flock_server.cpp BeOS port -beos/beos_flock_server.h BeOS port beos/nm.c BeOS port bytecode.pl Produces ext/ByteLoader/byterun.h, ext/ByteLoader/byterun.c and ext/B/Asmdata.pm cc_runtime.h Macros need by runtime of compiler-generated code diff --git a/Makefile.SH b/Makefile.SH index 1601cb7..192ce80 100644 --- a/Makefile.SH +++ b/Makefile.SH @@ -548,7 +548,7 @@ $(LIBPERL): $& perl$(OBJ_EXT) $(obj) $(LIBPERLEXPORT) !NO!SUBS! case "${osname}${osvers}" in - aix*) + aix*|beos*) $spitshell >>Makefile <<'!NO!SUBS!' miniperl: $& miniperlmain$(OBJ_EXT) $(LIBPERL) opmini$(OBJ_EXT) $(CC) -o miniperl $(CLDFLAGS) \ @@ -557,7 +557,7 @@ miniperl: $& miniperlmain$(OBJ_EXT) $(LIBPERL) opmini$(OBJ_EXT) $(LDLIBPTH) ./miniperl -w -Ilib -MExporter -e '' || $(MAKE) minitest !NO!SUBS! ;; - beos*|next4*) + next4*) $spitshell >>Makefile <<'!NO!SUBS!' miniperl: $& miniperlmain$(OBJ_EXT) $(LIBPERL) opmini$(OBJ_EXT) $(CC) -o miniperl `echo $(obj) | sed 's/ op$(OBJ_EXT) / /'` \ diff --git a/README.beos b/README.beos index cc9f44b..0a01f50 100644 --- a/README.beos +++ b/README.beos @@ -4,110 +4,106 @@ designed to be readable as is. =head1 NAME -README.beos - Perl version 5 on BeOS +README.beos - Perl version 5.8+ on BeOS =head1 DESCRIPTION -Notes for building Perl under BeOS. +This file contains instructions how to build Perl under BeOS and lists +known problems. -=head2 General Issues with Perl on BeOS +=head1 BUILD AND INSTALL -To compile perl under BeOS R4 x86: +=head2 Requirements - ./Configure -d +I have built and tested Perl 5.8.6 and 5.9.1 under BeOS R5 x86 net server. +I can't say anything with regard to PPC. Since Perl 5.8.0 had been released +for BeOS BONE, I suspect, there is a good chance, that it still compiles on +a BONE system. The only change I've made, that affects BONE systems is the +recognition of whether it is a BONE system or not in C. Now +network socket support should remain enabled on BONE systems. This might +as well break the build, though. -and hit ^C when it asks you if you want to make changes to config.sh; -edit config.sh and do the following: -change d_socket='define' to ='undef'; -remove SDBM, Errno, and Socket from dynamic_ext= and nonxs_ext=; -add '#define bool short' to x2p/a2p.h; +As more recent versions of autoconf require flock() support, I wrote a flock() +emulation (flock_server) and released it on BeBits: - ../Configure -S; make; make install + http://www.bebits.com/app/4030 - cd ~/config/lib; ln -s 5.00502/BeOS-BePC/CORE/libperl.so . +If you want to build a Perl with flock() support, you have to install this +package first. -(substitute 5.00502 with the appropriate filename) +=head2 Configure -=head2 BeOS Release-specific Notes +With flock() support: -=over 4 + CFLAGS=-I/path/to/flock/server/headers ./configure.gnu \ + --prefix=/boot/home/config -=item R4 x86 +Replace C with the path to the directory +containing the C header. -Dynamic loading finally works! Yay! This means you can compile your -own modules into perl. However, Sockets and Errno still don't work. -(Hopefully, sockets will at least work by R5, if not sooner.) +Without flock() support: -=item R4 PPC + ./configure.gnu --prefix=/boot/home/config -I have not tested this. I rather severely doubt that dynamic loading -will work. (My BeBox is in pieces right now, following a nasty disk -crash.) You may have to disable dynamic loading to get the thing to -compile at all. (use `./Configure` without -d, and say 'no' to 'Build -a shared libperl.so'.) +=head2 Build -=back +With flock() support: -=head2 Contact Information + make LDLOADLIBS="-lnet -lflock" -If you have comments, problem reports, or even patches or bugfixes (gasp!) -please email me. +Without flock() support: -28 Jan 1999 -Tom Spindler -dogcow@isi.net + make LDLOADLIBS="-lnet" -=head2 Update 2002-05-30 +C<-lnet> is needed on net server systems only and if the compiler doesn't +add it automatically (Be's R5 gcc does, Oliver Tappe's gcc 2.95.3 does not). -The following tests fail on 5.8.0 Perl in BeOS Personal 5.03: +=head2 Install - t/op/lfs............................FAILED at test 17 - t/op/magic..........................FAILED at test 24 - ext/Fcntl/t/syslfs..................FAILED at test 17 - ext/File/Glob/t/basic...............FAILED at test 3 - ext/POSIX/t/sigaction...............FAILED at test 13 - ext/POSIX/t/waitpid.................FAILED at test 1 +Install all perl files: -The reasons for the failures are as follows: + make install -=over 4 +Create a symlink for libperl: -=item * + cd ~/config/lib; ln -s perl5/5.8.6/BePC-beos/CORE/libperl.so . -The t/op/lfs and ext/Fcntl/t/syslfs failures indicate that the -LFS (large file support, files larger than 2 gigabytes) doesn't -work from Perl (BeFS itself is well capable of supporting large -files). What fails is that trying to position the file pointer -past 2 gigabytes doesn't work right, the position gets truncated -to its lower 32 bits. +Replace C<5.8.6> with your respective version of Perl. + +=head1 KNOWN PROBLEMS + +=over 4 =item * -The op/magic failures look like something funny going on with $0 and -$^X that I can't now figure out: none of the generated pathnames are -wrong as such, they just seem to accumulate "./" prefixes and infixes -in ways that define logic. +Network socket support is disabled for BeOS R5 net server. I didn't dare yet +to try enabling it and see what problems occur. =item * -The Glob/t/basic indicates a bug in the getpw*() functions: -they do not always return the correct user db entries. +The LFS (large file support) tests (C and C) are +disabled as seeking beyond 2 GB is broken according to jhi@iki.fi who was the +last one checking the BeOS port and updating this file before me. Haven't +checked this myself. =item * -The sigaction #13 means that signal mask doesn't get properly restored -if sigaction returns early. +The C test fails at #6. As far as I can tell, this is caused by +a bug in the BeOS pipes implementation that occurs when starting other child +processes. In the particular test case a C flushes the +stdout pipe of another child process. =item * -The waitpid failure means that after there are no more child -processes, waitpid is supposed to start returning -1 (and set -errno to ECHILD). In BeOS, it doesn't seem to. +The C test fails at #1. After all child processes are +gone BeOS' waitpid(-1,...) returns 0 instead of -1 (as it should). No idea +how to fix this. =back -Disclaimer: I just installed BeOS Personal Edition 5.0 and the -Developer Tools, that is the whole extent of my BeOS expertise, -so please don't ask me for further help in BeOS Perl problems. +=head1 CONTACT + +For BeOS specifics problems feel free to mail to: +Ingo Weinhold -jhi@iki.fi +Last update: 2004-12-16 diff --git a/beos/beos.c b/beos/beos.c index 4b5d992..755ce99 100644 --- a/beos/beos.c +++ b/beos/beos.c @@ -1,9 +1,8 @@ #include "beos/beosish.h" -#include "beos/beos_flock_server.h" #undef waitpid -#undef close #undef kill +#undef sigaction #include #include @@ -14,11 +13,6 @@ #include -/* We cache, for which FDs we got a lock. This will especially speed up close(), - since we won't have to contact the server. */ -#define FLOCK_TABLE_SIZE 256 -static int flockTable[FLOCK_TABLE_SIZE]; - /* In BeOS 5.0 the waitpid() seems to misbehave in that the status * has the upper and lower bytes swapped compared with the usual * POSIX/UNIX implementations. To undo the surpise effect to the @@ -34,162 +28,6 @@ pid_t beos_waitpid(pid_t process_id, int *status_location, int options) { return got; } -/* The flock() emulation worker function. */ - -static status_t beos_flock(int fd, int operation) { - static int serverPortInitialized = 0; - static port_id serverPort = -1; - - struct stat st; - int blocking; - port_id replyPort; - sem_id lockSem = -1; - status_t error; - flock_server_request request; - flock_server_reply *reply = NULL; - - if (fd < 0) - return B_BAD_VALUE; - - blocking = !(operation & LOCK_NB); - operation &= LOCK_SH | LOCK_EX | LOCK_UN; - - /* don't try to unlock something that isn't locked */ - if (operation == LOCK_UN && fd < FLOCK_TABLE_SIZE && !flockTable[fd]) - return B_OK; - - /* if not yet initialized, get the server port */ - if (!serverPortInitialized) { - serverPort = find_port(FLOCK_SERVER_PORT_NAME); - /* bonefish: If the port wasn't present at this point, we could start - * the server. In fact, I tried this and in works, but unfortunately - * it also seems to confuse our pipes (with both load_image() and - * system()). So, we can't help it, the server has to be started - * manually. */ - serverPortInitialized = ~0; - } - if (serverPort < 0) - return B_ERROR; - - /* stat() the file to get the node_ref */ - if (fstat(fd, &st) < 0) - return errno; - - /* create a reply port */ - replyPort = create_port(1, "flock reply port"); - if (replyPort < 0) - return replyPort; - - /* create a semaphore others will wait on while we own the lock */ - if (operation != LOCK_UN) { - char semName[64]; - sprintf(semName, "flock %ld:%lld\n", st.st_dev, st.st_ino); - lockSem = create_sem(0, semName); - if (lockSem < 0) { - delete_port(replyPort); - return lockSem; - } - } - - /* prepare the request */ - request.replyPort = replyPort; - request.lockSem = lockSem; - request.device = st.st_dev; - request.node = st.st_ino; - request.fd = fd; - request.operation = operation; - request.blocking = blocking; - - /* We ask the server to get us the requested lock for the file. - * The server returns semaphores for all existing locks (or will exist - * before it's our turn) that prevent us from getting the lock just now. - * We block on them one after the other and after that officially own the - * lock. If we told the server that we don't want to block, it will send - * an error code, if that is not possible. */ - - /* send the request */ - error = write_port(serverPort, 0, &request, sizeof(request)); - - if (error == B_OK) { - /* get the reply size */ - int replySize = port_buffer_size(replyPort); - if (replySize < 0) - error = replySize; - - /* allocate reply buffer */ - if (error == B_OK) { - reply = (flock_server_reply*)malloc(replySize); - if (!reply) - error = B_NO_MEMORY; - } - - /* read the reply */ - if (error == B_OK) { - int32 code; - ssize_t bytesRead = read_port(replyPort, &code, reply, replySize); - if (bytesRead < 0) { - error = bytesRead; - } else if (bytesRead != replySize) { - error = B_ERROR; - } - } - } - - /* get the error returned by the server */ - if (error == B_OK) - error = reply->error; - - /* wait for all lockers before us */ - if (error == B_OK) { - int i; - for (i = 0; i < reply->semaphoreCount; i++) - while (acquire_sem(reply->semaphores[i]) == B_INTERRUPTED); - } - - /* free the reply buffer */ - free(reply); - - /* delete the reply port */ - delete_port(replyPort); - - /* on failure delete the semaphore */ - if (error != B_OK) - delete_sem(lockSem); - - /* update the entry in the flock table */ - if (error == B_OK && fd < FLOCK_TABLE_SIZE) { - if (operation == LOCK_UN) - flockTable[fd] = 0; - else - flockTable[fd] = 1; - } - - return error; -} - -/* We implement flock() using a server. It is not really compliant with, since - * it would be very hard to track dup()ed FDs and those cloned as side-effect - * of fork(). Our locks are bound to the process (team) and a particular FD. - * I.e. a lock acquired by a team using a FD can only be unlocked by the same - * team using exactly the same FD (no other one pointing to the same file, not - * even when dup()ed from the original one). close()ing the FD releases the - * lock (that's why we need to override close()). On termination of the team - * all locks owned by the team will automatically be released. */ - -int flock(int fd, int operation) { - status_t error = beos_flock(fd, operation); - return (error == B_OK ? 0 : (errno = error, -1)); -} - -/* We need to override close() to release a potential lock on the FD. See - flock() for details */ - -int beos_close(int fd) { - flock(fd, LOCK_UN); - - return close(fd); -} - /* BeOS kill() doesn't like the combination of the pseudo-signal 0 and * specifying a process group (i.e. pid < -1 || pid == 0). We work around @@ -210,3 +48,20 @@ int beos_kill(pid_t pid, int sig) return kill(pid, sig); } + +/* sigaction() should fail, if trying to ignore or install a signal handler + * for a signal that cannot be caught or ignored. The BeOS R5 sigaction() + * doesn't return an error, though. */ +int beos_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact) +{ + int result = sigaction(sig, act, oact); + + if (result == 0 && act && act->sa_handler != SIG_DFL + && act->sa_handler != SIG_ERR && (sig == SIGKILL || sig == SIGSTOP)) { + result = -1; + errno = EINVAL; + } + + return result; +} diff --git a/beos/beos_flock_server.cpp b/beos/beos_flock_server.cpp deleted file mode 100644 index e075ce8..0000000 --- a/beos/beos_flock_server.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/* Server required for the flock() emulation under BeOS. */ -#include -#include -#include - -#include - -#include "beos_flock_server.h" - -/* debugging... */ -//#define PRINT(x) { printf x; } -#define PRINT(x) ; - -/* flock() operation flags */ -#define LOCK_SH (0x00) -#define LOCK_EX (0x01) -#define LOCK_UN (0x02) -#define LOCK_NB (0x04) - -enum { - MAX_WAITERS = 1024, - MAX_REPLY_SIZE = sizeof(flock_server_reply) + MAX_WAITERS * sizeof(sem_id) -}; - -/* A node_ref equivalent, so we don't need to link against libbe.so. */ -struct NodeRef { - NodeRef() : device(-1), node(-1) {} - NodeRef(dev_t device, ino_t node) : device(device), node(node) {} - - NodeRef& operator=(const NodeRef& other) - { - device = other.device; - node = other.node; - return *this; - } - - bool operator==(const NodeRef& other) const - { - return (device == other.device && node == other.node); - } - - dev_t device; - ino_t node; -}; - -/* Class representing a (potential) lock. */ -struct FlockEntry { - - FlockEntry(team_id team, sem_id lockSem, int fd, bool shared) - : team(team), - lockSem(lockSem), - fd(fd), - shared(shared), - next(NULL) - { - } - - ~FlockEntry() - { - if (lockSem >= 0) - delete_sem(lockSem); - } - - team_id team; - sem_id lockSem; - int fd; - bool shared; - - FlockEntry *next; -}; - -struct NodeRefHash -{ - size_t operator()(const NodeRef &nodeRef) const - { - uint32 hash = nodeRef.device; - hash = hash * 17 + (uint32)nodeRef.node; - hash = hash * 17 + (uint32)(nodeRef.node >> 32); - return hash; - } -}; - -typedef hash_map FlockEntryMap; -static FlockEntryMap sFlockEntries; - - -static status_t remove_lock(team_id team, flock_server_request &request, - flock_server_reply &reply); - -static void put_flock_entry(const NodeRef &nodeRef, FlockEntry *entry) -{ - sFlockEntries[nodeRef] = entry; -} - -static void remove_flock_entry(const NodeRef &nodeRef) -{ - sFlockEntries.erase(nodeRef); -} - - -static FlockEntry *get_flock_entry(const NodeRef &nodeRef) -{ - FlockEntryMap::iterator it = sFlockEntries.find(nodeRef); - if (it == sFlockEntries.end()) - return NULL; - FlockEntry *entry = it->second; - - /* remove all entries that are obsolete */ - FlockEntry *firstEntry = entry; - FlockEntry *previousEntry = NULL; - sem_info semInfo; - while (entry) { - if (get_sem_info(entry->lockSem, &semInfo) != B_OK) { - FlockEntry *oldEntry = entry; - entry = entry->next; - if (previousEntry) - previousEntry->next = oldEntry->next; - else - firstEntry = entry; - delete oldEntry; - } else { - previousEntry = entry; - entry = entry->next; - } - } - if (firstEntry) - put_flock_entry(nodeRef, firstEntry); - else - remove_flock_entry(nodeRef); - - return firstEntry; -} - -static FlockEntry *find_flock_entry(FlockEntry *entry, team_id team, int fd, - FlockEntry **_previousEntry = NULL) -{ - FlockEntry *previousEntry = NULL; - while (entry) { - if (entry->team == team && entry->fd == fd) { - /* found it */ - if (_previousEntry) - *_previousEntry = previousEntry; - return entry; - } - - previousEntry = entry; - entry = entry->next; - } - return entry; -} - -static status_t add_lock(team_id team, flock_server_request &request, - flock_server_reply &reply) -{ - bool shared = (request.operation == LOCK_SH); - - PRINT(("add_lock(): shared: %d, blocking: %d, file: (%ld, %lld), " - "team: %ld, fd: %d\n", shared, request.blocking, request.device, - request.node, team, request.fd)); - - // get the flock entry list - NodeRef nodeRef(request.device, request.node); - - FlockEntry *entry = get_flock_entry(nodeRef); - - reply.semaphoreCount = 0; - - /* special case: the caller already has the lock */ - if (entry && entry->team == team && entry->fd == request.fd) { - if (shared == entry->shared) - return B_OK; - - FlockEntry *nextEntry = entry->next; - if (!nextEntry) { - /* noone is waiting: just relabel the entry */ - entry->shared = shared; - delete_sem(request.lockSem); /* re-use the old semaphore */ - return B_OK; - } else if (shared) { - /* downgrade to shared lock: this is simple, if only share or - * exclusive lockers were waiting, but in mixed case we can - * neither just replace the semaphore nor just relabel the entry, - * but if mixed we have to surrender the exclusive lock and apply - * for a new one */ - - /* check, if there are only exclusive lockers waiting */ - FlockEntry *waiting = nextEntry; - bool onlyExclusiveWaiters = true; - while (waiting && onlyExclusiveWaiters) { - onlyExclusiveWaiters &= !waiting->shared; - waiting = waiting->next; - } - - if (onlyExclusiveWaiters) { - /* just relabel the entry */ - entry->shared = shared; - delete_sem(request.lockSem); /* re-use the old semaphore */ - return B_OK; - } - - /* check, if there are only shared lockers waiting */ - waiting = nextEntry; - bool onlySharedWaiters = true; - while (waiting && onlySharedWaiters) { - onlySharedWaiters &= waiting->shared; - waiting = waiting->next; - } - - if (onlySharedWaiters) { - /* replace the semaphore */ - delete_sem(entry->lockSem); - entry->lockSem = request.lockSem; - entry->shared = shared; - return B_OK; - } - - /* mixed waiters: fall through... */ - } else { - /* upgrade to exclusive lock: fall through... */ - } - - /* surrender the lock and re-lock */ - if (!request.blocking) - return B_WOULD_BLOCK; - flock_server_reply dummyReply; - remove_lock(team, request, dummyReply); - entry = nextEntry; - - /* fall through... */ - } - - /* add the semaphores of the preceding exclusive locks to the reply */ - FlockEntry* lastEntry = entry; - while (entry) { - if (!shared || !entry->shared) { - if (!request.blocking) - return B_WOULD_BLOCK; - - reply.semaphores[reply.semaphoreCount++] = entry->lockSem; - } - - lastEntry = entry; - entry = entry->next; - } - - /* create a flock entry and add it */ - FlockEntry *newEntry = new FlockEntry(team, request.lockSem, request.fd, - shared); - if (lastEntry) - lastEntry->next = newEntry; - else - put_flock_entry(nodeRef, newEntry); - - return B_OK; -} - -static status_t remove_lock(team_id team, flock_server_request &request, - flock_server_reply &reply) -{ - // get the flock entry list - NodeRef nodeRef(request.device, request.node); - - PRINT(("remove_lock(): file: (%ld, %lld), team: %ld, fd: %d\n", - request.device, request.node, team, request.fd)); - - // find the entry to be removed - FlockEntry *previousEntry = NULL; - FlockEntry *entry = find_flock_entry(get_flock_entry(nodeRef), team, - request.fd, &previousEntry); - - if (!entry) - return B_BAD_VALUE; - - /* remove the entry */ - if (previousEntry) { - previousEntry->next = entry->next; - } else { - if (entry->next) { - put_flock_entry(nodeRef, entry->next); - } else { - remove_flock_entry(nodeRef); - } - } - delete entry; - return B_OK; - -} - -int main(int argc, char** argv) { - /* get independent of our creator */ - setpgid(0, 0); - - /* create the request port */ - port_id requestPort = create_port(10, FLOCK_SERVER_PORT_NAME); - if (requestPort < 0) { - fprintf(stderr, "Failed to create request port: %s\n", - strerror(requestPort)); - exit(1); - } - - /* Check whether we are the first instance of the server. We do this by - * iterating through all teams and check, whether another team has a - * port with the respective port name. */ - { - /* get our team ID */ - thread_info threadInfo; - get_thread_info(find_thread(NULL), &threadInfo); - team_id thisTeam = threadInfo.team; - - /* iterate through all existing teams */ - int32 teamCookie = 0; - team_info teamInfo; - while (get_next_team_info(&teamCookie, &teamInfo) == B_OK) { - /* skip our own team */ - team_id team = teamInfo.team; - if (team == thisTeam) - continue; - - /* iterate through the team's ports */ - int32 portCookie = 0; - port_info portInfo; - while (get_next_port_info(team, &portCookie, &portInfo) == B_OK) { - if (strcmp(portInfo.name, FLOCK_SERVER_PORT_NAME) == 0) { - fprintf(stderr, "There's already a flock server running: " - "team: %ld\n", team); - delete_port(requestPort); - exit(1); - } - } - } - - /* Our creator might have supplied a semaphore we shall delete, when - * we're initialized. Note that this is still supported here, but - * due to problems with pipes the server is no longer started from - * our flock() in libperl.so, so it is not really used anymore. */ - if (argc >= 2) { - sem_id creatorSem = (argc >= 2 ? atol(argv[1]) : -1); - - /* check whether the semaphore really exists and belongs to our team - (our creator has transferred it to us) */ - sem_info semInfo; - if (creatorSem > 0 && get_sem_info(creatorSem, &semInfo) == B_OK - && semInfo.team == thisTeam) { - delete_sem(creatorSem); - } - } - } - - /* main request handling loop */ - while (true) { - /* read the request */ - flock_server_request request; - int32 code; - ssize_t bytesRead = read_port(requestPort, &code, &request, - sizeof(request)); - if (bytesRead != (int32)sizeof(request)) - continue; - - /* get the team */ - port_info portInfo; - if (get_port_info(request.replyPort, &portInfo) != B_OK) - continue; - team_id team = portInfo.team; - - char replyBuffer[MAX_REPLY_SIZE]; - flock_server_reply &reply = *(flock_server_reply*)replyBuffer; - - /* handle the request */ - status_t error = B_ERROR; - switch (request.operation) { - case LOCK_SH: - case LOCK_EX: - error = add_lock(team, request, reply); - break; - case LOCK_UN: - error = remove_lock(team, request, reply); - break; - } - - if (error == B_OK) { - PRINT((" -> successful\n")); - } else { - PRINT((" -> failed: %s\n", strerror(error))); - } - - /* prepare the reply */ - reply.error = error; - int32 replySize = sizeof(flock_server_reply); - if (error == B_OK) - replySize += reply.semaphoreCount * sizeof(sem_id) ; - - /* send the reply */ - write_port(request.replyPort, 0, &reply, replySize); - } - - return 0; -} diff --git a/beos/beos_flock_server.h b/beos/beos_flock_server.h deleted file mode 100644 index 2fb47e3..0000000 --- a/beos/beos_flock_server.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef PERL_BEOS_FLOCK_SERVER_H -#define PERL_BEOS_FLOCK_SERVER_H - -#include - -#define FLOCK_SERVER_PORT_NAME "perl flock server" - -typedef struct flock_server_request { - port_id replyPort; - sem_id lockSem; - dev_t device; - ino_t node; - int fd; - int operation; - int blocking; -} flock_server_request; - -typedef struct flock_server_reply { - status_t error; - int semaphoreCount; - sem_id semaphores[1]; -} flock_server_reply; - -#endif diff --git a/beos/beosish.h b/beos/beosish.h index d50cc55..7aab15f 100644 --- a/beos/beosish.h +++ b/beos/beosish.h @@ -11,24 +11,28 @@ pid_t beos_waitpid(pid_t process_id, int *status_location, int options); /* This seems to be protoless. */ char *gcvt(double value, int num_digits, char *buffer); +/* flock support, if available */ +#ifdef HAS_FLOCK -/* flock() operation flags */ -#define LOCK_SH (0x00) -#define LOCK_EX (0x01) -#define LOCK_UN (0x02) -#define LOCK_NB (0x04) - -int flock(int fd, int operation); +#include #undef close -#define close beos_close +#define close flock_close + +#undef dup2 +#define dup2 flock_dup2 -int beos_close(int fd); +#endif /* HAS_FLOCK */ #undef kill #define kill beos_kill int beos_kill(pid_t pid, int sig); +#undef sigaction +#define sigaction(sig, act, oact) beos_sigaction((sig), (act), (oact)) +int beos_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact); + #endif diff --git a/hints/beos.sh b/hints/beos.sh index 47e724b..a83b4af 100644 --- a/hints/beos.sh +++ b/hints/beos.sh @@ -48,9 +48,27 @@ if [ ! -f /boot/develop/headers/be/bone/sys/socket.h ]; then libs='-lnet' fi -# We provide a flock() emulation. -d_flock='define' -d_flockproto='define' +# There's a third party flock() emulation. Check, if it is available. +echo "#include " > try.c +if cc -E $CFLAGS try.c 2> /dev/null | grep "flock.*("; then + d_flock='define' + d_flockproto='define' + libs="$libs -lflock" + ldflags="$ldflags -L/boot/home/config/lib" +else + cat << 'EOM' >&4 + +I couldn't find a header defining a flock() prototype. That header +comes with the flock server package (available on BeBits). You have to add +the path to the directory containing the header via the environment variable +CFLAGS (should contain -I). Perl will be compiled +without flock() support, if the flock server package is not installed or the +header not found. + +EOM + +fi +rm try.c ld='gcc'