Merged first batch of BeOS port patches contributed by
authorwtc%netscape.com
Tue, 26 Jan 1999 01:56:55 +0000
changeset 400 0dfe1f25ef5bf64033a9964109227be9fb514005
parent 399 56f815a620143756766e09080d0118c1e7aa1df2
child 401 5cb6e099c0b729e237548b89dcdf1b3fa6f75117
push idunknown
push userunknown
push dateunknown
Merged first batch of BeOS port patches contributed by Matthew Zahorik <maz@albany.net>.
config/now.c
config/nsinstall.c
lib/ds/plevent.c
pr/include/md/Makefile
pr/include/md/_pth.h
pr/include/md/prosdep.h
pr/include/prinet.h
pr/include/prio.h
pr/include/private/primpl.h
pr/include/prtypes.h
pr/src/Makefile
pr/src/io/prfile.c
pr/src/io/prlog.c
pr/src/io/prmapopt.c
pr/src/io/prsocket.c
pr/src/linking/prlink.c
pr/src/md/Makefile
pr/src/md/prosdep.c
pr/src/misc/prinit.c
pr/src/misc/prtime.c
pr/src/threads/Makefile
pr/tests/op_filok.c
--- a/config/now.c
+++ b/config/now.c
@@ -14,17 +14,17 @@
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 #include <stdio.h>
 #include <stdlib.h>
 
-#if defined(XP_UNIX) || defined(XP_OS2_EMX)
+#if defined(XP_UNIX) || defined(XP_OS2_EMX) || defined(XP_BEOS)
 #include <sys/time.h>
 #elif defined(WIN32) || defined(XP_OS2_VACPP)
 #include <sys/timeb.h>
 #else
 #error "Architecture not supported"
 #endif
 
 
@@ -36,27 +36,29 @@ int main(int argc, char **argv)
      * such as 'long long'.  Because we can't use NSPR's
      * PR_snprintf in this program, it is difficult to
      * print a static initializer for PRInt64 (a struct).
      * So we print nothing.  The makefiles that build the
      * shared libraries will detect the empty output string
      * of this program and omit the library build time
      * in PRVersionDescription.
      */
-#elif defined(XP_UNIX) || defined(XP_OS2_EMX)
+#elif defined(XP_UNIX) || defined(XP_OS2_EMX) || defined(XP_BEOS)
     long long now;
     struct timeval tv;
 #ifdef HAVE_SVID_GETTOD
     gettimeofday(&tv);
 #else
     gettimeofday(&tv, NULL);
 #endif
     now = ((1000000LL) * tv.tv_sec) + (long long)tv.tv_usec;
 #if defined(OSF1)
     fprintf(stdout, "%ld", now);
+#elif defined(BEOS) && defined(__POWERPC__)
+    fprintf(stdout, "%Ld", now);  /* Metroworks on BeOS PPC */
 #else
     fprintf(stdout, "%lld", now);
 #endif
 
 #elif defined(WIN32)
     __int64 now;
     struct timeb b;
     ftime(&b);
--- a/config/nsinstall.c
+++ b/config/nsinstall.c
@@ -40,20 +40,27 @@
 #endif /* USE_REENTRANT_LIBC */
 
 #include "pathsub.h"
 
 #define HAVE_LCHOWN
 
 #if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) \
     || defined(SUNOS4) || defined(SCO) || defined(UNIXWARE) \
-    || defined(RHAPSODY) || defined(NEXTSTEP) || defined(QNX)
+    || defined(RHAPSODY) || defined(NEXTSTEP) || defined(QNX) \
+    || defined(BEOS)
 #undef HAVE_LCHOWN
 #endif
 
+#define HAVE_FCHMOD
+
+#if defined(BEOS)
+#undef HAVE_FCHMOD
+#endif
+
 /*
  * Does getcwd() take NULL as the first argument and malloc
  * the result buffer?
  */
 #if !defined(RHAPSODY) && !defined(NEXTSTEP)
 #define GETCWD_CAN_MALLOC
 #endif
 
@@ -352,17 +359,21 @@ main(int argc, char **argv)
 	    if (ftruncate(tofd, sb.st_size) < 0)
 		fail("cannot truncate %s", toname);
 	    if (dotimes) {
 		utb.actime = sb.st_atime;
 		utb.modtime = sb.st_mtime;
 		if (utime(toname, &utb) < 0)
 		    fail("cannot set times of %s", toname);
 	    }
+#ifdef HAVE_FCHMOD
 	    if (fchmod(tofd, mode) < 0)
+#else
+	    if (chmod(toname, mode) < 0)
+#endif
 		fail("cannot change mode of %s", toname);
 	    if ((owner || group) && fchown(tofd, uid, gid) < 0)
 		fail("cannot change owner of %s", toname);
 
 	    /* Must check for delayed (NFS) write errors on close. */
 	    if (close(tofd) < 0)
 		fail("cannot write to %s", toname);
 	    close(fromfd);
--- a/lib/ds/plevent.c
+++ b/lib/ds/plevent.c
@@ -641,16 +641,24 @@ static PRStatus
     unsigned char buf[] = { NOTIFY_TOKEN };
 
     count = write(self->eventPipe[1], buf, 1);
 	self->notifyCount++;
     return (count == 1) ? PR_SUCCESS : PR_FAILURE;
 }/* --- end _pl_NativeNotify() --- */
 #endif /* XP_UNIX */
 
+#if defined(XP_BEOS)
+static PRStatus
+_pl_NativeNotify(PLEventQueue* self)
+{
+    return PR_SUCCESS;    /* Is this correct? */
+}
+#endif /* XP_BEOS */
+
 #if defined(XP_MAC)
 static PRStatus
 _pl_NativeNotify(PLEventQueue* self)
 {
 #pragma unused (self)
     return PR_SUCCESS;    /* XXX can fail? */
 }
 #endif /* XP_MAC */
@@ -923,17 +931,17 @@ static void _md_CreateEventQueue( PLEven
                                                        NULL,
                                                        NULL);
     PR_ASSERT(eventQueue->eventReceiverWindow);
 
     return;    
 } /* end _md_CreateEventQueue() */
 #endif /* XP_OS2 */
 
-#if defined(XP_UNIX) || defined(XP_MAC)
+#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS)
 /*
 ** _md_CreateEventQueue() -- ModelDependent initializer
 */
 static void _md_CreateEventQueue( PLEventQueue *eventQueue )
 {
     /* there's really nothing special to do here,
     ** the guts of the unix stuff is in the setupnativenotify
     ** and related functions.
--- a/pr/include/md/Makefile
+++ b/pr/include/md/Makefile
@@ -126,16 +126,20 @@ endif
 ifeq ($(OS_ARCH),DGUX)
 MDCPUCFG_H = _dgux.cfg
 endif
 
 ifeq ($(OS_ARCH),QNX)
 MDCPUCFG_H = _qnx.cfg
 endif
 
+ifeq ($(OS_ARCH),BeOS)
+MDCPUCFG_H = _beos.cfg
+endif
+
 export:: $(HEADERS) $(MDCPUCFG_H)
 	$(INSTALL) -m 444 $(HEADERS) $(DIST)/include/md
 	$(INSTALL) -m 444 $(MDCPUCFG_H) $(DIST)/include
 ifeq ($(MOZ_BITS),16)
 	cp $(DIST)/include/$(MDCPUCFG_H) $(DIST)/include/prcpucfg.h
 	$(INSTALL) -m 444 $(HEADERS) $(MOZ_INCL)/md
 	$(INSTALL) -m 444 $(MDCPUCFG_H) $(MOZ_INCL)
 	mv -f $(DIST)/include/$(MDCPUCFG_H) $(MOZ_INCL)/prcpucfg.h
--- a/pr/include/md/_pth.h
+++ b/pr/include/md/_pth.h
@@ -221,19 +221,11 @@ extern int (*_PT_aix_yield_fcn)();
 #elif defined(HPUX) || defined(LINUX) || defined(SOLARIS) \
 	|| defined(FREEBSD) || defined(NETBSD) || defined(OPENBSD) \
 	|| defined(BSDI)
 #define PTHREAD_YIELD()            	sched_yield()
 #else
 #error "Need to define PTHREAD_YIELD for this platform"
 #endif
 
-/*
-** And when you really wanted hardcore locking w/o any fluff ...
-**
-**          ... and why would you want that????
-*/
-#define _PR_LOCK_LOCK(_lock)      pthread_mutex_lock(&_lock->mutex);
-#define _PR_LOCK_UNLOCK(_lock)    pthread_mutex_unlock(&_lock->mutex);
-
 #define _MD_INIT_LOCKS()
 
 #endif /* nspr_pth_defs_h_ */
--- a/pr/include/md/prosdep.h
+++ b/pr/include/md/prosdep.h
@@ -116,19 +116,24 @@ PR_BEGIN_EXTERN_C
 #else
 #error unknown Unix flavor
 
 #endif
 
 #include "md/_unixos.h"
 #include "md/_unix_errors.h"
 
+#elif defined(XP_BEOS)
+
+#include "md/_beos.h"
+#include "md/_unix_errors.h"
+
 #else
 
-#error "The platform is not Unix, Windows, or Mac"
+#error "The platform is not BeOS, Unix, Windows, or Mac"
 
 #endif
 
 #ifdef _PR_PTHREADS
 #include "md/_pth.h"
 #endif
 
 PR_END_EXTERN_C
--- a/pr/include/prinet.h
+++ b/pr/include/prinet.h
@@ -35,24 +35,25 @@
  *       the same names on all supported platforms.
  *     This file is intended to be included by nspr20 public header
  *     files, such as prio.h.  One should not include this file directly.
  */
 
 #ifndef prinet_h__
 #define prinet_h__
 
-#if defined(XP_UNIX) || defined(XP_OS2)
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
 
 #include <sys/types.h>
 #include <sys/socket.h>		/* AF_INET */
 #include <netinet/in.h>         /* INADDR_ANY, ..., ntohl(), ... */
 #ifdef XP_OS2
 #include <sys/ioctl.h>
-#else
+#endif
+#ifdef XP_UNIX
 #include <arpa/inet.h>
 #endif
 #include <netdb.h>
 
 #if defined(FREEBSD) || defined(BSDI) || defined(QNX)
 #include <rpc/types.h> /* the only place that defines INADDR_LOOPBACK */
 #endif
 
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -129,23 +129,31 @@ typedef enum PRTransmitFileFlags {
 
 typedef struct in6_addr PRIPv6Addr;
 
 #endif /* defined(_PR_INET6) */
 
 union PRNetAddr {
     struct {
         PRUint16 family;                /* address family (0x00ff maskable) */
+#ifdef XP_BEOS
+        char data[10];                  /* Be has a smaller structure */
+#else
         char data[14];                  /* raw address data */
+#endif
     } raw;
     struct {
         PRUint16 family;                /* address family (AF_INET) */
         PRUint16 port;                  /* port number */
         PRUint32 ip;                    /* The actual 32 bits of address */
+#ifdef XP_BEOS
+        char pad[4];                    /* Be has a smaller structure */
+#else
         char pad[8];
+#endif
     } inet;
 #if defined(_PR_INET6)
     struct {
         PRUint16 family;                /* address family (AF_INET6) */
         PRUint16 port;                  /* port number */
         PRUint32 flowinfo;              /* routing information */
         PRIPv6Addr ip;                  /* the actual 128 bits of address */
     } ipv6;
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -26,16 +26,20 @@
  * This macro causes chaos if signal.h gets included before pthread.h.
  * To be safe, we include pthread.h first.
  */
 
 #if defined(_PR_PTHREADS)
 #include <pthread.h>
 #endif
 
+#if defined(_PR_BTHREADS)
+#include <kernel/OS.h>
+#endif
+
 #ifdef WINNT
 /* Need to force service-pack 3 extensions to be defined by
 ** setting _WIN32_WINNT to NT 4.0 for winsock.h, winbase.h, winnt.h.
 */
 #ifndef  _WIN32_WINNT
     #define _WIN32_WINNT 0x0400
 #elif   (_WIN32_WINNT < 0x0400)
     #undef  _WIN32_WINNT
@@ -1215,38 +1219,45 @@ PR_EXTERN(void) _PR_MD_START_INTERRUPTS(
 PR_EXTERN(void) _PR_MD_INIT_LOCKS(void);
 #define    _PR_MD_INIT_LOCKS _MD_INIT_LOCKS
 
 struct PRLock {
 #if defined(_PR_PTHREADS)
     pthread_mutex_t mutex;          /* the underlying lock */
     _PT_Notified notified;          /* array of conditions notified */
     pthread_t owner;                /* current lock owner */
-#else  /* defined(_PR_PTHREADS) */
+#elif defined(_PR_BTHREADS)
+    sem_id	semaphoreID;	    /* the underlying lock */
+    int32	benaphoreCount;	    /* number of people in lock */
+    thread_id	owner;		    /* current lock owner */
+#else /* not pthreads or Be threads */
     PRCList links;                  /* linkage for PRThread.lockList */
     struct PRThread *owner;         /* current lock owner */
     PRCList waitQ;                  /* list of threads waiting for lock */
     PRThreadPriority priority;      /* priority of lock */ 
     PRThreadPriority boostPriority; /* boosted priority of lock owner */
     _MDLock ilock;                  /* Internal Lock to protect user-level fields */
-#endif /* defined(_PR_PTHREADS) */
+#endif
 };
 
 extern void _PR_InitLocks(void);
 
 struct PRCondVar {
     PRLock *lock;               /* associated lock that protects the condition */
 #if defined(_PR_PTHREADS)
     pthread_cond_t cv;          /* underlying pthreads condition */
     PRInt32 notify_pending;     /* CV has destroy pending notification */
-#else  /* defined(_PR_PTHREADS) */
+#elif defined(_PR_BTHREADS)
+    sem_id	isem;		/* Semaphore used to lock threadQ */
+    int32	benaphoreCount; /* Number of people in lock */
+#else /* not pthreads or Be threads */
     PRCList condQ;              /* Condition variable wait Q */
     _MDLock ilock;              /* Internal Lock to protect condQ */
     _MDCVar md;
-#endif /* defined(_PR_PTHREADS) */
+#endif
 };
 
 /************************************************************************/
 
 struct PRMonitor {
     const char* name;           /* monitor name for debugging */
 #if defined(_PR_PTHREADS)
     PRLock lock;                /* the lock struture structure */
@@ -1256,23 +1267,28 @@ struct PRMonitor {
     PRCondVar *cvar;            /* associated lock and condition variable queue */
 #endif /* defined(_PR_PTHREADS) */
     PRUint32 entryCount;        /* # of times re-entered */
 };
 
 /************************************************************************/
 
 struct PRSemaphore {
+#if defined(_PR_BTHREADS)
+    sem_id  sem;
+    int32   benaphoreCount;
+#else
     PRCondVar *cvar;        /* associated lock and condition variable queue */
     PRUintn count;            /* the value of the counting semaphore */
     PRUint32 waiters;            /* threads waiting on the semaphore */
 #if defined(_PR_PTHREADS)
 #else  /* defined(_PR_PTHREADS) */
     _MDSemaphore md;
 #endif /* defined(_PR_PTHREADS) */
+#endif /* defined(_PR_BTHREADS) */
 };
 
 PR_EXTERN(void) _PR_InitSem(void);
 
 /************************************************************************/
 
 /* XXX this needs to be exported (sigh) */
 struct PRThreadStack {
@@ -1335,17 +1351,23 @@ struct PRThread {
     PRCondVar *waiting;             /* where the thread is waiting | NULL */
     void *sp;                       /* recorded sp for garbage collection */
     PRThread *next, *prev;          /* simple linked list of all threads */
     PRUint32 suspend;               /* used to store suspend and resume flags */
 #ifdef PT_NO_SIGTIMEDWAIT
     pthread_mutex_t suspendResumeMutex;
     pthread_cond_t suspendResumeCV;
 #endif
-#else /* defined(_PR_PTHREADS) */
+#elif defined(_PR_BTHREADS)
+    PRUint32 flags;
+    _MDThread md;
+    PRBool io_pending;
+    PRInt32 io_fd;
+    PRBool io_suspended;
+#else /* not pthreads or Be threads */
     _MDLock threadLock;             /* Lock to protect thread state variables.
                                      * Protects the following fields:
                                      *     state
                                      *     priority
                                      *     links
                                      *     wait
                                      *     cpu
                                      */
@@ -1400,17 +1422,17 @@ struct PRThread {
      * OS doesn't support a real cancellation (NT or MAC), then the 
      * io_suspended flag will be set to true.  The thread will be resumed
      * but may run into trouble issuing additional IOs until the io_pending
      * flag can be cleared 
      */
     PRBool io_suspended;
 
     _MDThread md;
-#endif /* defined(_PR_PTHREADS) */
+#endif
 };
 
 struct PRProcessAttr {
     PRFileDesc *stdinFd;
     PRFileDesc *stdoutFd;
     PRFileDesc *stderrFd;
     char *currentDirectory;
     char *fdInheritBuffer;
@@ -1678,11 +1700,28 @@ extern PRStatus _PR_MD_CLOSE_FILE_MAP(PR
 
 PR_EXTERN(PRInt32) _PR_MD_GET_SOCKET_ERROR(void);
 #define    _PR_MD_GET_SOCKET_ERROR _MD_GET_SOCKET_ERROR
 
 /* Get name of current host */
 extern PRStatus _PR_MD_GETHOSTNAME(char *name, PRUint32 namelen);
 #define    _PR_MD_GETHOSTNAME _MD_GETHOSTNAME
 
+#ifdef XP_BEOS
+
+extern PRLock *_connectLock;
+
+typedef struct _ConnectListNode {
+	PRInt32		osfd;
+	PRNetAddr	addr;
+	PRUint32	addrlen;
+	PRIntervalTime	timeout;
+} ConnectListNode;
+
+extern ConnectListNode connectList[64];
+
+extern PRUint32 connectCount;
+
+#endif /* XP_BEOS */
+
 PR_END_EXTERN_C
 
 #endif /* primpl_h___ */
--- a/pr/include/prtypes.h
+++ b/pr/include/prtypes.h
@@ -30,16 +30,20 @@
 ** for all C files.
 **/
 
 #ifndef prtypes_h___
 #define prtypes_h___
 
 #include "prcpucfg.h"
 
+#ifdef XP_BEOS
+#include <support/SupportDefs.h>
+#endif
+
 #include <stddef.h>
 
 /***********************************************************************
 ** MACROS:      PR_EXTERN
 **              PR_IMPLEMENT
 ** DESCRIPTION:
 **      These are only for externally visible routines and globals.  For
 **      internal routines, just use "extern" for type checking and that
@@ -62,16 +66,26 @@
 #define PR_IMPLEMENT(__type) _declspec(dllexport) __type
 #define PR_EXTERN_DATA(__type) extern _declspec(dllexport) __type
 #define PR_IMPLEMENT_DATA(__type) _declspec(dllexport) __type
 
 #define PR_CALLBACK
 #define PR_CALLBACK_DECL
 #define PR_STATIC_CALLBACK(__x) static __x
 
+#elif defined(XP_BEOS)
+#define PR_EXTERN(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT(__type) __declspec(dllexport) __type
+#define PR_EXTERN_DATA(__type) extern __declspec(dllexport) __type
+#define PR_IMPLEMENT_DATA(__type) __declspec(dllexport) __type
+
+#define PR_CALLBACK
+#define PR_CALLBACK_DECL
+#define PR_STATIC_CALLBACK(__x) static __x
+
 #elif defined(WIN16)
 
 #define PR_CALLBACK_DECL        __cdecl
 
 #if defined(_WINDLL)
 #define PR_EXTERN(__type) extern __type _cdecl _export _loadds
 #define PR_IMPLEMENT(__type) __type _cdecl _export _loadds
 #define PR_EXTERN_DATA(__type) extern __type _export
--- a/pr/src/Makefile
+++ b/pr/src/Makefile
@@ -22,16 +22,20 @@ MOD_DEPTH = ../..
 include $(MOD_DEPTH)/config/config.mk
 
 DIRS = io linking malloc md memory misc threads
 
 ifeq ($(USE_PTHREADS), 1)
 	DIRS += pthreads
 endif
 
+ifeq ($(USE_BTHREADS), 1)
+	DIRS += bthreads
+endif
+
 ifeq ($(USE_CPLUS), 1)
 	DIRS += cplus
 endif
 
 #
 # Define platform-dependent OS_LIBS
 #
 
@@ -190,28 +194,33 @@ OBJS += \
     pthreads/$(OBJDIR)/ptio.$(OBJ_SUFFIX) \
     pthreads/$(OBJDIR)/ptthread.$(OBJ_SUFFIX) \
     pthreads/$(OBJDIR)/ptmisc.$(OBJ_SUFFIX)
 else
 OBJS += \
     io/$(OBJDIR)/prdir.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prfile.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prio.$(OBJ_SUFFIX) \
-    io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/prsocket.$(OBJ_SUFFIX)
+
+ifndef USE_BTHREADS
+OBJS += \
 	threads/$(OBJDIR)/prcthr.$(OBJ_SUFFIX) \
 	threads/$(OBJDIR)/prdump.$(OBJ_SUFFIX) \
 	threads/$(OBJDIR)/prmon.$(OBJ_SUFFIX) \
 	threads/$(OBJDIR)/prsem.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prucpu.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
 endif
 
+endif
+
 ifeq ($(USE_IPV6), 1)
 OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
 endif
 
 ifeq ($(USE_CPLUS), 1)
 OBJS += \
 	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
@@ -296,18 +305,23 @@ OBJS +=	md/windows/$(OBJDIR)/ntdllmn.$(O
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)
 endif
 endif
 endif
 
 else
 
-# Unix
-include md/unix/objs.mk
+ifeq ($(OS_ARCH), BeOS)
+	include md/beos/objs.mk
+	include bthreads/objs.mk
+else
+	# Unix
+	include md/unix/objs.mk
+endif
 
 endif
 
 LIBRARY_NAME = nspr
 LIBRARY_VERSION = $(MOD_VERSION)
 
 RELEASE_LIBS = $(TARGETS)
 
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -291,17 +291,17 @@ PRInt32 PR_GetSysfdTableMax(void)
 #elif defined(WIN32) || defined(OS2)
     /*
      * There is a systemwide limit of 65536 user handles.
      * Not sure on OS/2, but sounds good.
      */
     return 16384;
 #elif defined (WIN16)
     return FOPEN_MAX;
-#elif defined (XP_MAC)
+#elif defined (XP_MAC) || defined(XP_BEOS)
     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return -1;
 #else
     write me;
 #endif
 }
 
 PRInt32 PR_SetSysfdTableSize(int table_size)
@@ -326,17 +326,18 @@ PRInt32 PR_SetSysfdTableSize(int table_s
 
     if ( setrlimit(RLIMIT_NOFILE, &rlim) < 0) {
         /* XXX need to call PR_SetError() */
         return -1;
     }
 
     return rlim.rlim_cur;
 #elif defined(AIX) || defined(NEXTSTEP) || defined(QNX) \
-        || defined(WIN32) || defined(WIN16) || defined(OS2)
+        || defined(WIN32) || defined(WIN16) || defined(OS2) \
+        || defined(XP_BEOS)
     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
     return -1;
 #elif defined (XP_MAC)
 #pragma unused (table_size)
     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return -1;
 #else
     write me;
--- a/pr/src/io/prlog.c
+++ b/pr/src/io/prlog.c
@@ -25,17 +25,20 @@
  * Lock used to lock the log.
  *
  * We can't define _PR_LOCK_LOG simply as PR_Lock because PR_Lock may
  * contain assertions.  We have to avoid assertions in _PR_LOCK_LOG
  * because PR_ASSERT calls PR_LogPrint, which in turn calls _PR_LOCK_LOG.
  * This can lead to infinite recursion.
  */
 static PRLock *_pr_logLock;
-#if (defined(_PR_PTHREADS) || defined(_PR_GLOBAL_THREADS_ONLY))
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
+#define _PR_LOCK_LOG() PR_Lock(_pr_logLock);
+#define _PR_UNLOCK_LOG() PR_Unlock(_pr_logLock);
+#elif defined(_PR_GLOBAL_THREADS_ONLY)
 #define _PR_LOCK_LOG() { _PR_LOCK_LOCK(_pr_logLock)
 #define _PR_UNLOCK_LOG() _PR_LOCK_UNLOCK(_pr_logLock); }
 #else
 
 #define _PR_LOCK_LOG() \
 { \
     PRIntn _is; \
     PRThread *_me = _PR_MD_CURRENT_THREAD(); \
@@ -388,16 +391,18 @@ PR_IMPLEMENT(void) PR_LogPrint(const cha
     va_start(ap, fmt);
     me = PR_GetCurrentThread();
     nb = PR_snprintf(line, sizeof(line)-1, "%ld[%p]: ",
 #if defined(_PR_DCETHREADS)
              /* The problem is that for _PR_DCETHREADS, pthread_t is not a 
               * pointer, but a structure; so you can't easily print it...
               */
                      me ? &(me->id): 0L, me);
+#elif defined(_PR_BTHREADS)
+		     me, me);
 #else
                      me ? me->id : 0L, me);
 #endif
 
     nb += PR_vsnprintf(line+nb, sizeof(line)-nb-1, fmt, ap);
     if (nb && (line[nb-1] != '\n')) {
 #ifndef XP_MAC
         line[nb++] = '\n';
@@ -457,17 +462,17 @@ PR_IMPLEMENT(void) PR_Abort(void)
 #endif /* PR_LOGGING */
         PR_ASSERT(1);
 }
 
 PR_IMPLEMENT(void) PR_Assert(const char *s, const char *file, PRIntn ln)
 {
 #ifdef PR_LOGGING
     PR_LogPrint("Assertion failure: %s, at %s:%d\n", s, file, ln);
-#if defined(XP_UNIX) || defined(XP_OS2)
+#if defined(XP_UNIX) || defined(XP_OS2) || defined(XP_BEOS)
     fprintf(stderr, "Assertion failure: %s, at %s:%d\n", s, file, ln);
 #endif
 #ifdef XP_MAC
     dprintf("Assertion failure: %s, at %s:%d\n", s, file, ln);
 #endif
 #ifdef WIN32
     DebugBreak();
 #endif
--- a/pr/src/io/prmapopt.c
+++ b/pr/src/io/prmapopt.c
@@ -65,29 +65,34 @@ PRStatus PR_CALLBACK _PR_SocketGetSocket
 
     rv = _PR_MapOptionName(data->option, &level, &name);
     if (PR_SUCCESS == rv)
     {
         switch (data->option)
         {
             case PR_SockOpt_Linger:
             {
+#if !defined(XP_BEOS)
                 struct linger linger;
                 length = sizeof(linger);
                 rv = _PR_MD_GETSOCKOPT(
                     fd, level, name, (char *) &linger, &length);
                 if (PR_SUCCESS == rv)
                 {
                     PR_ASSERT(sizeof(linger) == length);
                     data->value.linger.polarity =
                         (linger.l_onoff) ? PR_TRUE : PR_FALSE;
                     data->value.linger.linger =
                         PR_SecondsToInterval(linger.l_linger);
                 }
                 break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
             }
             case PR_SockOpt_Reuseaddr:
             case PR_SockOpt_Keepalive:
             case PR_SockOpt_NoDelay:
             {
 #ifdef WIN32 /* Winsock */
                 BOOL value;
 #else
@@ -217,22 +222,27 @@ PRStatus PR_CALLBACK _PR_SocketSetSocket
 
     rv = _PR_MapOptionName(data->option, &level, &name);
     if (PR_SUCCESS == rv)
     {
         switch (data->option)
         {
             case PR_SockOpt_Linger:
             {
+#if !defined(XP_BEOS)
                 struct linger linger;
                 linger.l_onoff = data->value.linger.polarity;
                 linger.l_linger = PR_IntervalToSeconds(data->value.linger.linger);
                 rv = _PR_MD_SETSOCKOPT(
                     fd, level, name, (char*)&linger, sizeof(linger));
                 break;
+#else
+                PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+                return PR_FAILURE;
+#endif
             }
             case PR_SockOpt_Reuseaddr:
             case PR_SockOpt_Keepalive:
             case PR_SockOpt_NoDelay:
             {
 #ifdef WIN32 /* Winsock */
                 BOOL value;
 #else
@@ -361,16 +371,28 @@ PRStatus PR_CALLBACK _PR_SocketSetSocket
 #endif
 
 /*
  * Make sure the value of _PR_NO_SUCH_SOCKOPT is not
  * a valid socket option.
  */
 #define _PR_NO_SUCH_SOCKOPT -1
 
+#ifndef SO_KEEPALIVE
+#define SO_KEEPALIVE        _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_SNDBUF
+#define SO_SNDBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
+#ifndef SO_RCVBUF
+#define SO_RCVBUF           _PR_NO_SUCH_SOCKOPT
+#endif
+
 #ifndef IP_MULTICAST_IF                 /* set/get IP multicast interface   */
 #define IP_MULTICAST_IF     _PR_NO_SUCH_SOCKOPT
 #endif
 
 #ifndef IP_MULTICAST_TTL                /* set/get IP multicast timetolive  */
 #define IP_MULTICAST_TTL    _PR_NO_SUCH_SOCKOPT
 #endif
 
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -290,16 +290,26 @@ PR_IMPLEMENT(PRStatus) PR_GetConnectStat
 #elif defined(XP_MAC)
 
     err = _MD_mac_get_nonblocking_connect_error(osfd);
     if (err == -1)
         return PR_FAILURE;
 	else     
 		return PR_SUCCESS;
 
+#elif defined(XP_BEOS)
+
+    err = _MD_beos_get_nonblocking_connect_error(bottom);
+    if( err != 0 ) {
+	_PR_MD_MAP_CONNECT_ERROR(err);
+	return PR_FAILURE;
+    }
+    else
+	return PR_SUCCESS;
+
 #else
     PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
     return PR_FAILURE;
 #endif
 }
 
 static PRFileDesc* PR_CALLBACK SocketAccept(PRFileDesc *fd, PRNetAddr *addr,
 PRIntervalTime timeout)
@@ -900,28 +910,33 @@ static PRStatus PR_CALLBACK SocketGetSoc
         return PR_SUCCESS;
     }
 
     rv = _PR_MapOptionName(optname, &level, &name);
     if (PR_SUCCESS == rv)
     {
         if (PR_SockOpt_Linger == optname)
         {
+#if !defined(XP_BEOS)
             struct linger linger;
             PRInt32 len = sizeof(linger);
             rv = _PR_MD_GETSOCKOPT(
                 fd, level, name, (char *) &linger, &len);
             if (PR_SUCCESS == rv)
             {
                 ((PRLinger*)(optval))->polarity = linger.l_onoff
                     ? PR_TRUE : PR_FALSE;
                 ((PRLinger*)(optval))->linger = PR_SecondsToInterval(
                     linger.l_linger);
                 *optlen = sizeof(PRLinger);
             }
+#else
+            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+            return PR_FAILURE;
+#endif
         }
         else
         {
             rv = _PR_MD_GETSOCKOPT(
                 fd, level, name, (char*)optval, optlen);
         }
     }
     return rv;
@@ -961,22 +976,27 @@ static PRStatus PR_CALLBACK SocketSetSoc
         return PR_SUCCESS;
     }
 
     rv = _PR_MapOptionName(optname, &level, &name);
     if (PR_SUCCESS == rv)
     {
         if (PR_SockOpt_Linger == optname)
         {
+#if !defined(XP_BEOS)
             struct linger linger;
             linger.l_onoff = ((PRLinger*)(optval))->polarity ? 1 : 0;
             linger.l_linger = PR_IntervalToSeconds(
                 ((PRLinger*)(optval))->linger);
             rv = _PR_MD_SETSOCKOPT(
                 fd, level, name, (char *) &linger, sizeof(linger));
+#else
+            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
+            return PR_FAILURE;
+#endif
         }
         else
         {
             rv = _PR_MD_SETSOCKOPT(
                 fd, level, name, (const char*)optval, optlen);
         }
     }
     return rv;
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -15,16 +15,20 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 #include "primpl.h"
 
 #include <string.h>
 
+#ifdef XP_BEOS
+#include <image.h>
+#endif
+
 #ifdef XP_MAC
 #include <CodeFragments.h>
 #include <TextUtils.h>
 #include <Types.h>
 #include <Strings.h>
 #endif
 
 #ifdef XP_UNIX
@@ -72,16 +76,20 @@ struct PRLibrary {
 #if defined(USE_HPSHL)
     shl_t                       dlh;
 #elif defined(USE_MACH_DYLD)
     NSModule                    dlh;
 #else
     void*                       dlh;
 #endif 
 #endif 
+
+#ifdef XP_BEOS
+    void*			dlh;
+#endif
 };
 
 static PRLibrary *pr_loadmap;
 static PRLibrary *pr_exe_loadmap;
 static PRMonitor *pr_linker_lock;
 static char* _pr_currentLibPath = NULL;
 
 /************************************************************************/
@@ -370,24 +378,24 @@ PR_GetLibraryName(const char *path, cons
         fullname = PR_smprintf("%s\\%s%s", path, lib, PR_DLL_SUFFIX);
     } else {
         fullname = PR_smprintf("%s\\%s", path, lib);
     }
 #endif /* XP_PC */
 #ifdef XP_MAC
     fullname = PR_smprintf("%s%s", path, lib);
 #endif
-#ifdef XP_UNIX
+#if defined(XP_UNIX) || defined(XP_BEOS)
     if (strstr(lib, PR_DLL_SUFFIX) == NULL)
     {
         fullname = PR_smprintf("%s/lib%s%s", path, lib, PR_DLL_SUFFIX);
     } else {
         fullname = PR_smprintf("%s/%s", path, lib);
     }
-#endif /* XP_UNIX */
+#endif /* XP_UNIX || XP_BEOS */
     return fullname;
 }
 
 /*
 ** Free the memory allocated, for the caller, by PR_GetLibraryName
 */
 PR_IMPLEMENT(void) 
 PR_FreeLibraryName(char *mem)
@@ -637,16 +645,35 @@ PR_LoadLibrary(const char *name)
     pr_loadmap = lm;
     }
 #elif defined(XP_MAC) && !GENERATINGCFM
     {
 
     }
 #endif
 
+#ifdef XP_BEOS
+    {
+	image_id h = load_add_on( name );
+
+	if( h == B_ERROR || h <= 0 ) {
+
+	    h = 0;
+	    result = NULL;
+	    PR_DELETE( lm );
+	    lm = NULL;
+	    goto unlock;
+	}
+	lm->name = strdup(name);
+	lm->dlh = (void*)h;
+	lm->next = pr_loadmap;
+	pr_loadmap = lm;
+    }
+#endif
+
 #ifdef XP_UNIX
 #ifdef HAVE_DLL
     {
 #if defined(USE_DLFCN)
     void *h = dlopen(name, RTLD_LAZY);
 #elif defined(USE_HPSHL)
     shl_t h = shl_load(name, BIND_DEFERRED | DYNAMIC_PATH, 0L);
 #elif defined(USE_MACH_DYLD)
@@ -711,16 +738,21 @@ PR_UnloadLibrary(PRLibrary *lib)
 
     PR_EnterMonitor(pr_linker_lock);
     if (--lib->refCount > 0) {
     PR_LOG(_pr_linker_lm, PR_LOG_MIN,
            ("%s decr => %d",
         lib->name, lib->refCount));
     goto done;
     }
+
+#ifdef XP_BEOS
+    unload_add_on( (image_id) lib->dlh );
+#endif
+
 #ifdef XP_UNIX
 #ifdef HAVE_DLL
 #ifdef USE_DLFCN
     result = dlclose(lib->dlh);
 #elif defined(USE_HPSHL)
     result = shl_unload(lib->dlh);
 #elif defined(USE_MACH_DYLD)
     result = NSUnLinkModule(lib->dlh, FALSE);
@@ -796,17 +828,17 @@ pr_FindSymbolInLib(PRLibrary *lm, const 
         if (strcmp(name, tp->name) == 0) {
         return (void*) tp->fp;
         }
     }
         /* 
         ** If the symbol was not found in the static table then check if
         ** the symbol was exported in the DLL... Win16 only!!
         */
-#if !defined(WIN16)
+#if !defined(WIN16) && !defined(XP_BEOS)
         PR_SetError(PR_FIND_SYMBOL_ERROR, 0);
         return (void*)NULL;
 #endif
     }
     
 #ifdef XP_OS2
     DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
 #endif  /* XP_OS2 */
@@ -822,16 +854,23 @@ pr_FindSymbolInLib(PRLibrary *lm, const 
     Str255        pName;
             
         PStrFromCStr(name, pName);    
         
         f = (NSFindSymbol(lm->dlh, pName, &symAddr, &symClass) == noErr) ? symAddr : NULL;
     }
 #endif /* XP_MAC */
 
+#ifdef XP_BEOS
+    if( B_NO_ERROR != get_image_symbol( (image_id)lm->dlh, name, B_SYMBOL_TYPE_TEXT, &f ) ) {
+
+	f = NULL;
+    }
+#endif
+
 #ifdef XP_UNIX
 #ifdef HAVE_DLL
 #ifdef USE_DLFCN
     f = dlsym(lm->dlh, name);
 #elif defined(USE_HPSHL)
     if (shl_findsym(&lm->dlh, name, TYPE_PROCEDURE, &f) == -1) {
         f = NULL;
     }
--- a/pr/src/md/Makefile
+++ b/pr/src/md/Makefile
@@ -23,17 +23,21 @@ include $(MOD_DEPTH)/config/config.mk
 
 ifeq ($(OS_ARCH),WINNT)
   ifeq ($(OS_TARGET),OS2)
     DIRS = os2
   else
     DIRS = windows
   endif
 else
-  DIRS = unix
+  ifeq ($(OS_ARCH),BeOS)
+    DIRS = beos
+  else
+    DIRS = unix
+  endif
 endif
 
 # Disable optimization of the nspr on SunOS4.1.3
 ifeq ($(OS_ARCH),SunOS)
 ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
--- a/pr/src/md/prosdep.c
+++ b/pr/src/md/prosdep.c
@@ -23,16 +23,19 @@
 #include <unistd.h>
 #endif
 #ifdef SUNOS4
 #include "md/sunos4.h"
 #endif
 #ifdef _WIN32
 #include <windows.h>
 #endif 
+#ifdef XP_BEOS
+#include <OS.h>
+#endif
 
 PRInt32 _pr_pageShift;
 PRInt32 _pr_pageSize;
 
 /*
 ** Get system page size
 */
 static void GetPageSize(void)
@@ -52,16 +55,20 @@ static void GetPageSize(void)
     _pr_pageSize = sysconf(_SC_PAGESIZE);
 #endif
 #endif /* XP_UNIX */
 
 #ifdef XP_MAC
     _pr_pageSize = 4096;
 #endif /* XP_MAC */
 
+#ifdef XP_BEOS
+    _pr_pageSize = B_PAGE_SIZE;
+#endif
+
 #ifdef XP_PC
 #ifdef _WIN32
     SYSTEM_INFO info;
     GetSystemInfo(&info);
     _pr_pageSize = info.dwPageSize;
 #else
     _pr_pageSize = 4096;
 #endif
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -28,17 +28,17 @@ PRLogModuleInfo *_pr_linker_lm;
 PRLogModuleInfo *_pr_sched_lm;
 PRLogModuleInfo *_pr_thread_lm;
 PRLogModuleInfo *_pr_gc_lm;
 
 PRFileDesc *_pr_stdin;
 PRFileDesc *_pr_stdout;
 PRFileDesc *_pr_stderr;
 
-#if !defined(_PR_PTHREADS)
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
 
 PRCList _pr_active_local_threadQ =
 			PR_INIT_STATIC_CLIST(&_pr_active_local_threadQ);
 PRCList _pr_active_global_threadQ =
 			PR_INIT_STATIC_CLIST(&_pr_active_global_threadQ);
 
 _MDLock  _pr_cpuLock;           /* lock for the CPU Q */
 PRCList _pr_cpuQ = PR_INIT_STATIC_CLIST(&_pr_cpuQ);
@@ -161,45 +161,45 @@ void _PR_ImplicitInitialization()
 #ifndef _PR_GLOBAL_THREADS_ONLY
     _PR_MD_START_INTERRUPTS();
 #endif
 
 }
 
 PR_IMPLEMENT(void) PR_DisableClockInterrupts(void)
 {
-#if !defined(_PR_PTHREADS)
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
 	if (!_pr_initialized) {
 		_PR_InitStuff();
 	} else {
     	_PR_MD_DISABLE_CLOCK_INTERRUPTS();
 	}
 #endif
 }
 
 PR_IMPLEMENT(void) PR_EnableClockInterrupts(void)
 {
-#if !defined(_PR_PTHREADS)
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
 	if (!_pr_initialized) {
 		_PR_InitStuff();
 	}
     _PR_MD_ENABLE_CLOCK_INTERRUPTS();
 #endif
 }
 
 PR_IMPLEMENT(void) PR_BlockClockInterrupts(void)
 {
-#if !defined(_PR_PTHREADS)
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
     	_PR_MD_BLOCK_CLOCK_INTERRUPTS();
 #endif
 }
 
 PR_IMPLEMENT(void) PR_UnblockClockInterrupts(void)
 {
-#if !defined(_PR_PTHREADS)
+#if !defined(_PR_PTHREADS) && !defined(_PR_BTHREADS)
     	_PR_MD_UNBLOCK_CLOCK_INTERRUPTS();
 #endif
 }
 
 PR_IMPLEMENT(void) PR_Init(
     PRThreadType type, PRThreadPriority priority, PRUintn maxPTDs)
 {
 #if defined(XP_MAC)
@@ -232,17 +232,17 @@ PR_IMPLEMENT(PRIntn) PR_Initialize(
  *   We first do the cleanup generic to all platforms.  Then
  *   we call _PR_MD_CLEANUP_BEFORE_EXIT(), where platform-dependent
  *   cleanup is done.  This function is used by PR_Cleanup().
  *
  * See also: PR_Cleanup().
  *
  *-----------------------------------------------------------------------
  */
-#if defined(_PR_PTHREADS)
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
     /* see ptthread.c */
 #else
 static void
 _PR_CleanupBeforeExit(void)
 {
 /* 
 Do not make any calls here other than to destroy resources.  For example,
 do not make any calls that eventually may end up in PR_Lock.  Because the
@@ -279,17 +279,17 @@ thread is destroyed, can not access curr
  *   
  *   PR_Cleanup() only responds when it is called by the primordial
  *   thread. Calls by any other thread are silently ignored.
  *
  * See also: PR_ExitProcess()
  *
  *----------------------------------------------------------------------
  */
-#if defined(_PR_PTHREADS)
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
     /* see ptthread.c */
 #else
 
 PR_IMPLEMENT(PRStatus) PR_Cleanup()
 {
     PRThread *me = PR_GetCurrentThread();
     PR_ASSERT((NULL != me) && (me->flags & _PR_PRIMORDIAL));
     if ((NULL != me) && (me->flags & _PR_PRIMORDIAL))
@@ -370,17 +370,17 @@ PR_IMPLEMENT(PRStatus) PR_Cleanup()
  *   It takes a PRIntn argument, which is the exit status code of the
  *   process.
  *   
  * See also: PR_Cleanup()
  *
  *------------------------------------------------------------------------
  */
 
-#if defined(_PR_PTHREADS)
+#if defined(_PR_PTHREADS) || defined(_PR_BTHREADS)
     /* see ptthread.c */
 #else
 PR_IMPLEMENT(void) PR_ProcessExit(PRIntn status)
 {
     _PR_MD_EXIT(status);
 }
 
 #endif /* defined(_PR_PTHREADS) */
--- a/pr/src/misc/prtime.c
+++ b/pr/src/misc/prtime.c
@@ -604,17 +604,17 @@ static struct tm *MT_safe_localtime(cons
 
     if (needLock) PR_Unlock(monitor);
 
     return result;
 }
 
 #endif  /* definition of MT_safe_localtime() */
 
-#if defined(XP_UNIX) || defined(XP_PC)
+#if defined(XP_UNIX) || defined(XP_PC) || defined(XP_BEOS)
 
 PR_IMPLEMENT(PRTimeParameters)
 PR_LocalTimeParameters(const PRExplodedTime *gmt)
 {
 
     PRTimeParameters retVal;
     struct tm localTime;
     time_t secs;
--- a/pr/src/threads/Makefile
+++ b/pr/src/threads/Makefile
@@ -19,41 +19,52 @@
 
 MOD_DEPTH = ../../..
 
 include $(MOD_DEPTH)/config/config.mk
 
 ifdef USE_PTHREADS
     DIRS =
 else
+ifdef USE_BTHREADS
+    DIRS =
+else
     DIRS = combined
 endif
+endif
 
 # Disable optimization of the nspr on SunOS4.1.3
 ifeq ($(OS_ARCH),SunOS)
 ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 ifdef USE_PTHREADS
 CSRCS = \
 	prcmon.c \
 	prtpd.c \
 	$(NULL)
 else
+ifdef USE_BTHREADS
+CSRCS = \
+	prcmon.c \
+	prtpd.c \
+	$(NULL)
+else
 CSRCS =	\
 	prcmon.c  \
 	prdump.c  \
 	prmon.c   \
 	prsem.c   \
 	prcthr.c \
 	prtpd.c \
 	$(NULL)
 endif
+endif
 
 TARGETS	= $(OBJS)
 
 INCLUDES = -I$(DIST)/include/private -I$(DIST)/include
 
 include $(MOD_DEPTH)/config/rules.mk
 
 export:: $(TARGETS)
--- a/pr/tests/op_filok.c
+++ b/pr/tests/op_filok.c
@@ -47,16 +47,18 @@
  * on every machine of a particular OS.
  */
 #ifdef XP_UNIX
 #define EXISTING_FILENAME "/bin/sh"
 #elif defined(WIN32)
 #define EXISTING_FILENAME "c:/boot.ini"
 #elif defined(OS2)
 #define EXISTING_FILENAME "c:/config.sys"
+#elif defined(BEOS)
+#define EXISTING_FILENAME "/boot/beos/bin/sh"
 #else
 #error "Unknown OS"
 #endif
 
 static PRFileDesc *t1;
 
 int main(int argc, char **argv)
 {