Re: [perl #32717] BeOS specific Updates
bonefish@cs.tu-berlin.de [Fri, 17 Dec 2004 01:17:40 +0000 (02:17 +0100)]
Message-Id: <20041217011740.14398.1@cs.tu-berlin.de>

p4raw-id: //depot/perl@23661

MANIFEST
Makefile.SH
README.beos
beos/beos.c
beos/beos_flock_server.cpp [deleted file]
beos/beos_flock_server.h [deleted file]
beos/beosish.h
hints/beos.sh

index 3d96603..219da18 100644 (file)
--- 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
index 1601cb7..192ce80 100644 (file)
@@ -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) / /'` \
index cc9f44b..0a01f50 100644 (file)
@@ -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<hints/beos.sh>. 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</path/to/flock/server/headers> with the path to the directory
+containing the C<flock.h> 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<t/op/lfs> and C<xt/Fcntl/t/syslfs>) 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<t/io/fflush> 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<system("perl -e 0")> 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<ext/POSIX/t/waitpid> 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 <bonefish@cs.tu-berlin.de>
 
-jhi@iki.fi
+Last update: 2004-12-16
index 4b5d992..755ce99 100644 (file)
@@ -1,9 +1,8 @@
 #include "beos/beosish.h"
-#include "beos/beos_flock_server.h"
 
 #undef waitpid
-#undef close
 #undef kill
+#undef sigaction
 
 #include <errno.h>
 #include <signal.h>
 
 #include <OS.h>
 
-/* 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 (file)
index e075ce8..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/* Server required for the flock() emulation under BeOS. */
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include <hash_map.h>
-
-#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<NodeRef, FlockEntry*, NodeRefHash> 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 (file)
index 2fb47e3..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-#ifndef PERL_BEOS_FLOCK_SERVER_H
-#define PERL_BEOS_FLOCK_SERVER_H
-
-#include <OS.h>
-
-#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
index d50cc55..7aab15f 100644 (file)
@@ -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 <flock.h>
 
 #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
 
index 47e724b..a83b4af 100644 (file)
@@ -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 <flock.h>" > 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 <flock.h> 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</path/to/dir/of/flock/header>). 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'