initial LOCAL_THREAD_ONLY rhapsody work RHAPSODY_NSPR_BRANCH
authortoshok
Wed, 22 Apr 1998 07:53:07 +0000
branchRHAPSODY_NSPR_BRANCH
changeset 56 070915eb1e7773e9397e75268074d022b87f41ad
parent 53 47e0294b04faed9e08b7bd2a16e163d5839e12ba
child 83 04bcb0e10bbf58c32ffa0c7923c712b505d0b710
push idunknown
push userunknown
push dateunknown
initial LOCAL_THREAD_ONLY rhapsody work
config/Rhapsody.mk
config/nsinstall.c
pr/include/md/Makefile
pr/include/md/_darwin.cfg
pr/include/md/_darwin.h
pr/include/md/_rhapsody.cfg
pr/include/md/_rhapsody.h
pr/include/md/_unixos.h
pr/include/md/prosdep.h
pr/include/private/primpl.h
pr/src/linking/prlink.c
pr/src/md/prosdep.c
pr/src/md/unix/Makefile
pr/src/md/unix/darwin.c
pr/src/md/unix/objs.mk
pr/src/md/unix/rhapsody.c
pr/src/md/unix/unix.c
pr/src/md/unix/unix_errors.c
pr/src/md/unix/uxwrap.c
pr/src/memory/prseg.c
new file mode 100644
--- /dev/null
+++ b/config/Rhapsody.mk
@@ -0,0 +1,46 @@
+#
+# The contents of this file are subject to the Netscape Public License
+# Version 1.0 (the "NPL"); you may not use this file except in
+# compliance with the NPL.  You may obtain a copy of the NPL at
+# http://www.mozilla.org/NPL/
+# 
+# Software distributed under the NPL is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+# for the specific language governing rights and limitations under the
+# NPL.
+# 
+# The Initial Developer of this code under the NPL is Netscape
+# Communications Corporation.  Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+# Reserved.
+#
+
+#
+# Config stuff for Rhapsody5.0
+#
+
+include $(MOD_DEPTH)/config/UNIX.mk
+
+CC			= cc
+CCC			= cc++
+RANLIB			= ranlib
+
+OS_REL_CFLAGS		= -Dppc
+CPU_ARCH		= ppc
+
+#OS_REL_CFLAGS		= -mno-486 -Di386
+#CPU_ARCH		= x86
+
+OS_CFLAGS		= $(DSO_CFLAGS) $(OS_REL_CFLAGS) -pipe -DRHAPSODY -DHAVE_STRERROR -DHAVE_BSD_FLOCK
+
+DEFINES			+= -D_PR_LOCAL_THREADS_ONLY -D_PR_NEED_FAKE_POLL
+
+ARCH			= rhapsody
+
+#DSO_CFLAGS		= -fPIC
+#DSO_LDOPTS		= -Bshareable
+#DSO_LDFLAGS		=
+
+#MKSHLIB			= $(LD) $(DSO_LDOPTS)
+
+#G++INCLUDES		= -I/usr/include/g++
--- a/config/nsinstall.c
+++ b/config/nsinstall.c
@@ -32,17 +32,17 @@
 #include <unistd.h>
 #include <utime.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include "pathsub.h"
 
 #define HAVE_LCHOWN
 
-#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SUNOS4) || defined(SCO) || defined(UNIXWARE)
+#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SUNOS4) || defined(SCO) || defined(UNIXWARE) || defined(RHAPSODY)
 #undef HAVE_LCHOWN
 #endif
 
 #ifdef LINUX
 #include <getopt.h>
 #endif
 
 #if defined(SCO) || defined(UNIXWARE) || defined(SNI) || defined(NCR) || defined(NEC)
--- a/pr/include/md/Makefile
+++ b/pr/include/md/Makefile
@@ -54,16 +54,20 @@ endif
 ifeq ($(OS_ARCH),FreeBSD)
 MDCPUCFG_H = _freebsd.cfg
 endif
 
 ifeq ($(OS_ARCH),HP-UX)
 MDCPUCFG_H = _hpux.cfg
 endif
 
+ifeq ($(OS_ARCH),Rhapsody)
+MDCPUCFG_H = _rhapsody.cfg
+endif
+
 ifeq ($(OS_ARCH),Linux)
 MDCPUCFG_H = _linux.cfg
 endif
 
 ifeq ($(OS_ARCH),OSF1)
 MDCPUCFG_H = _osf1.cfg
 endif
 
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_darwin.cfg
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RHAPOSDY
+#define RHAPOSDY
+#endif
+
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_darwin.h
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#ifndef nspr_rhapsody_defs_h___
+#define nspr_rhapsody_defs_h___
+
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"rhapsody"
+#define _PR_SI_SYSNAME  "RHAPSODY"
+#ifdef i386
+#define _PR_SI_ARCHITECTURE "x86"
+#else
+#define _PR_SI_ARCHITECTURE "ppc"
+#endif
+#define PR_DLL_SUFFIX		".so.1.0"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_WEAK_MALLOC_SYMBOLS
+/* do this until I figure out the rhapsody dll stuff. */
+#define HAVE_DLL
+#define USE_RLD
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_GET_SP(_th)    (_th)->md.context[2]
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * XXX: Rhapsody doesn't have poll(), but our pthreads code calls poll().
+ * As a temporary measure, I implemented a fake poll() using select().
+ * Here are the struct and macro definitions copied from sys/poll.h
+ * on Solaris 2.5.
+ */
+
+struct pollfd {
+    int fd;
+    short events;
+    short revents;
+};
+
+/* poll events */
+
+#define	POLLIN		0x0001		/* fd is readable */
+#define	POLLPRI		0x0002		/* high priority info at fd */
+#define	POLLOUT		0x0004		/* fd is writeable (won't block) */
+#define	POLLRDNORM	0x0040		/* normal data is readable */
+#define	POLLWRNORM	POLLOUT
+#define	POLLRDBAND	0x0080		/* out-of-band data is readable */
+#define	POLLWRBAND	0x0100		/* out-of-band data is writeable */
+
+#define	POLLNORM	POLLRDNORM
+
+#define	POLLERR		0x0008		/* fd has error condition */
+#define	POLLHUP		0x0010		/* fd has been hung up on */
+#define	POLLNVAL	0x0020		/* invalid pollfd entry */
+
+extern int poll(struct pollfd *, unsigned long, int);
+
+#endif /* _PR_NEED_FAKE_POLL */
+
+#endif /* nspr_rhapsody_defs_h___ */
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_rhapsody.cfg
@@ -0,0 +1,119 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#ifndef nspr_cpucfg___
+#define nspr_cpucfg___
+
+#ifndef XP_UNIX
+#define XP_UNIX
+#endif
+
+#ifndef RHAPOSDY
+#define RHAPOSDY
+#endif
+
+#undef IS_LITTLE_ENDIAN
+#define  IS_BIG_ENDIAN 1
+#define	HAVE_LONG_LONG
+#undef	HAVE_ALIGNED_DOUBLES
+#define	HAVE_ALIGNED_LONGLONGS 1
+
+#define PR_BYTES_PER_BYTE   1
+#define PR_BYTES_PER_SHORT  2
+#define PR_BYTES_PER_INT    4
+#define PR_BYTES_PER_INT64  8
+#define PR_BYTES_PER_LONG   4
+#define PR_BYTES_PER_FLOAT  4
+#define PR_BYTES_PER_DOUBLE 8
+#define PR_BYTES_PER_WORD   4
+#define PR_BYTES_PER_DWORD  8
+#define PR_BYTES_PER_WORD_LOG2   2
+#define PR_BYTES_PER_DWORD_LOG2  3
+
+#define PR_BITS_PER_BYTE    8
+#define PR_BITS_PER_SHORT   16
+#define PR_BITS_PER_INT     32
+#define PR_BITS_PER_INT64   64
+#define PR_BITS_PER_LONG    32
+#define PR_BITS_PER_FLOAT   32
+#define PR_BITS_PER_DOUBLE  64
+#define PR_BITS_PER_WORD    32
+
+#define PR_BITS_PER_BYTE_LOG2   3
+#define PR_BITS_PER_SHORT_LOG2  4
+#define PR_BITS_PER_INT_LOG2    5
+#define PR_BITS_PER_INT64_LOG2  6
+#define PR_BITS_PER_LONG_LOG2   5
+#define PR_BITS_PER_FLOAT_LOG2  5
+#define PR_BITS_PER_DOUBLE_LOG2 6
+#define PR_BITS_PER_WORD_LOG2   5
+
+#define PR_ALIGN_OF_SHORT   2
+#define PR_ALIGN_OF_INT     4
+#define PR_ALIGN_OF_LONG    4
+#define PR_ALIGN_OF_INT64   4
+#define PR_ALIGN_OF_FLOAT   4
+#define PR_ALIGN_OF_DOUBLE  4
+#define PR_ALIGN_OF_POINTER 4
+
+#ifndef NO_NSPR_10_SUPPORT
+
+#define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
+#define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
+#define BYTES_PER_INT 		PR_BYTES_PER_INT
+#define BYTES_PER_INT64		PR_BYTES_PER_INT64
+#define BYTES_PER_LONG		PR_BYTES_PER_LONG
+#define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
+#define BYTES_PER_DOUBLE	PR_BYTES_PER_DOUBLE
+#define BYTES_PER_WORD		PR_BYTES_PER_WORD
+#define BYTES_PER_DWORD		PR_BYTES_PER_DWORD
+
+#define BITS_PER_BYTE		PR_BITS_PER_BYTE
+#define BITS_PER_SHORT		PR_BITS_PER_SHORT
+#define BITS_PER_INT		PR_BITS_PER_INT
+#define BITS_PER_INT64		PR_BITS_PER_INT64
+#define BITS_PER_LONG		PR_BITS_PER_LONG
+#define BITS_PER_FLOAT		PR_BITS_PER_FLOAT
+#define BITS_PER_DOUBLE		PR_BITS_PER_DOUBLE
+#define BITS_PER_WORD		PR_BITS_PER_WORD
+
+#define BITS_PER_BYTE_LOG2	PR_BITS_PER_BYTE_LOG2
+#define BITS_PER_SHORT_LOG2	PR_BITS_PER_SHORT_LOG2
+#define BITS_PER_INT_LOG2	PR_BITS_PER_INT_LOG2
+#define BITS_PER_INT64_LOG2	PR_BITS_PER_INT64_LOG2
+#define BITS_PER_LONG_LOG2	PR_BITS_PER_LONG_LOG2
+#define BITS_PER_FLOAT_LOG2	PR_BITS_PER_FLOAT_LOG2
+#define BITS_PER_DOUBLE_LOG2 	PR_BITS_PER_DOUBLE_LOG2
+#define BITS_PER_WORD_LOG2	PR_BITS_PER_WORD_LOG2
+
+#define ALIGN_OF_SHORT		PR_ALIGN_OF_SHORT
+#define ALIGN_OF_INT		PR_ALIGN_OF_INT
+#define ALIGN_OF_LONG		PR_ALIGN_OF_LONG
+#define ALIGN_OF_INT64		PR_ALIGN_OF_INT64
+#define ALIGN_OF_FLOAT		PR_ALIGN_OF_FLOAT
+#define ALIGN_OF_DOUBLE		PR_ALIGN_OF_DOUBLE
+#define ALIGN_OF_POINTER	PR_ALIGN_OF_POINTER
+#define ALIGN_OF_WORD		PR_ALIGN_OF_WORD
+
+#define BYTES_PER_WORD_LOG2	PR_BYTES_PER_WORD_LOG2
+#define BYTES_PER_DWORD_LOG2	PR_BYTES_PER_DWORD_LOG2
+#define WORDS_PER_DWORD_LOG2	PR_WORDS_PER_DWORD_LOG2
+
+#endif /* NO_NSPR_10_SUPPORT */
+
+#endif /* nspr_cpucfg___ */
new file mode 100644
--- /dev/null
+++ b/pr/include/md/_rhapsody.h
@@ -0,0 +1,177 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#ifndef nspr_rhapsody_defs_h___
+#define nspr_rhapsody_defs_h___
+
+#include <sys/syscall.h>
+
+#define PR_LINKER_ARCH	"rhapsody"
+#define _PR_SI_SYSNAME  "RHAPSODY"
+#ifdef i386
+#define _PR_SI_ARCHITECTURE "x86"
+#else
+#define _PR_SI_ARCHITECTURE "ppc"
+#endif
+#define PR_DLL_SUFFIX		".so.1.0"
+
+#define _PR_VMBASE              0x30000000
+#define _PR_STACK_VMBASE	0x50000000
+#define _MD_DEFAULT_STACK_SIZE	65536L
+#define _MD_MMAP_FLAGS          MAP_PRIVATE
+
+#undef  HAVE_STACK_GROWING_UP
+#define HAVE_WEAK_MALLOC_SYMBOLS
+/* do this until I figure out the rhapsody dll stuff. */
+#define HAVE_DLL
+#define USE_RLD
+
+#define USE_SETJMP
+
+#include <setjmp.h>
+
+#define PR_CONTEXT_TYPE	jmp_buf
+
+#define CONTEXT(_th) ((_th)->md.context)
+
+#define _MD_GET_SP(_th)    (_th)->md.context[2]
+#define PR_NUM_GCREGS	_JBLEN
+
+/*
+** Initialize a thread context to run "_main()" when started
+*/
+#define _MD_INIT_CONTEXT(_thread, _sp, _main, status)  \
+{  \
+    *status = PR_TRUE;  \
+    if (setjmp(CONTEXT(_thread))) {  \
+        _main();  \
+    }  \
+    _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \
+}
+
+#define _MD_SWITCH_CONTEXT(_thread)  \
+    if (!setjmp(CONTEXT(_thread))) {  \
+	(_thread)->md.errcode = errno;  \
+	_PR_Schedule();  \
+    }
+
+/*
+** Restore a thread context, saved by _MD_SWITCH_CONTEXT
+*/
+#define _MD_RESTORE_CONTEXT(_thread) \
+{   \
+    errno = (_thread)->md.errcode;  \
+    _MD_SET_CURRENT_THREAD(_thread);  \
+    longjmp(CONTEXT(_thread), 1);  \
+}
+
+/* Machine-dependent (MD) data structures */
+
+struct _MDThread {
+    PR_CONTEXT_TYPE context;
+    int id;
+    int errcode;
+};
+
+struct _MDThreadStack {
+    PRInt8 notused;
+};
+
+struct _MDLock {
+    PRInt8 notused;
+};
+
+struct _MDSemaphore {
+    PRInt8 notused;
+};
+
+struct _MDCVar {
+    PRInt8 notused;
+};
+
+struct _MDSegment {
+    PRInt8 notused;
+};
+
+struct _MDCPU {
+	struct _MDCPU_Unix md_unix;
+};
+
+#define _MD_INIT_LOCKS()
+#define _MD_NEW_LOCK(lock) PR_SUCCESS
+#define _MD_FREE_LOCK(lock)
+#define _MD_LOCK(lock)
+#define _MD_UNLOCK(lock)
+#define _MD_INIT_IO()
+#define _MD_IOQ_LOCK()
+#define _MD_IOQ_UNLOCK()
+
+#define _MD_INIT_RUNNING_CPU(cpu)       _MD_unix_init_running_cpu(cpu)
+#define _MD_INIT_THREAD                 _MD_InitializeThread
+#define _MD_EXIT_THREAD(thread)
+#define _MD_SUSPEND_THREAD(thread)      _MD_suspend_thread
+#define _MD_RESUME_THREAD(thread)       _MD_resume_thread
+#define _MD_CLEAN_THREAD(_thread)
+
+#define _MD_EARLY_INIT                  _MD_EarlyInit
+#define _MD_FINAL_INIT			_PR_UnixInit
+#define _MD_GET_INTERVAL                  _PR_UNIX_GetInterval
+#define _MD_INTERVAL_PER_SEC              _PR_UNIX_TicksPerSecond
+
+/*
+ * We wrapped the select() call.  _MD_SELECT refers to the built-in,
+ * unwrapped version.
+ */
+#define _MD_SELECT(nfds,r,w,e,tv) syscall(SYS_select,nfds,r,w,e,tv)
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+/*
+ * XXX: Rhapsody doesn't have poll(), but our pthreads code calls poll().
+ * As a temporary measure, I implemented a fake poll() using select().
+ * Here are the struct and macro definitions copied from sys/poll.h
+ * on Solaris 2.5.
+ */
+
+struct pollfd {
+    int fd;
+    short events;
+    short revents;
+};
+
+/* poll events */
+
+#define	POLLIN		0x0001		/* fd is readable */
+#define	POLLPRI		0x0002		/* high priority info at fd */
+#define	POLLOUT		0x0004		/* fd is writeable (won't block) */
+#define	POLLRDNORM	0x0040		/* normal data is readable */
+#define	POLLWRNORM	POLLOUT
+#define	POLLRDBAND	0x0080		/* out-of-band data is readable */
+#define	POLLWRBAND	0x0100		/* out-of-band data is writeable */
+
+#define	POLLNORM	POLLRDNORM
+
+#define	POLLERR		0x0008		/* fd has error condition */
+#define	POLLHUP		0x0010		/* fd has been hung up on */
+#define	POLLNVAL	0x0020		/* invalid pollfd entry */
+
+extern int poll(struct pollfd *, unsigned long, int);
+
+#endif /* _PR_NEED_FAKE_POLL */
+
+#endif /* nspr_rhapsody_defs_h___ */
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -44,17 +44,17 @@
 
 /* To pick up fd_set */
 #if defined(HPUX)
 #include <sys/time.h>
 #elif defined(OSF1) || defined(AIX) || defined(SOLARIS) || defined(IRIX) \
         || defined(UNIXWARE) || defined(NCR) || defined(SNI) || defined(NEC) \
         || defined(BSDI) || defined(SONY)
 #include <sys/select.h>
-#elif defined(SUNOS4) || defined(SCO) || defined(FREEBSD)
+#elif defined(SUNOS4) || defined(SCO) || defined(FREEBSD) || defined(RHAPSODY)
 #include <sys/types.h>
 #elif defined(LINUX)
 #include <sys/time.h>
 #include <sys/types.h>
 #else
 #error Find out what include file defines fd_set on this platform
 #endif
 
@@ -140,17 +140,17 @@ extern void _MD_unix_init_running_cpu(st
 
 
 /*
 ** Make a redzone at both ends of the stack segment. Disallow access
 ** to those pages of memory. It's ok if the mprotect call's don't
 ** work - it just means that we don't really have a functional
 ** redzone.
 */
-#if defined(DEBUG)
+#if defined(DEBUG) && !defined(RHAPSODY)
 #if !defined(SOLARIS)	
 #include <string.h>  /* for memset() */
 #define _MD_INIT_STACK(ts,REDZONE)					\
     PR_BEGIN_MACRO                 					\
 	(void) mprotect((void*)ts->seg->vaddr, REDZONE, PROT_NONE);	\
 	(void) mprotect((void*) ((char*)ts->seg->vaddr + REDZONE + ts->stackSize),\
 			REDZONE, PROT_NONE);				\
     /*									\
--- a/pr/include/md/prosdep.h
+++ b/pr/include/md/prosdep.h
@@ -69,16 +69,19 @@ PR_BEGIN_EXTERN_C
 #include "md/_irix.h"
 
 #elif defined(LINUX)
 #include "md/_linux.h"
 
 #elif defined(OSF1)
 #include "md/_osf1.h"
 
+#elif defined(RHAPSODY)
+#include "md/_rhapsody.h"
+
 #elif defined(SOLARIS)
 #include "md/_solaris.h"
 
 #elif defined(SUNOS4)
 #include "md/_sunos4.h"
 
 #elif defined(SNI)
 #include "md/_reliantunix.h"
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -1466,16 +1466,17 @@ extern PRBool _pr_ipv6_enabled;  /* defi
 /* Overriding malloc, free, etc. */
 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
         && (!defined(SOLARIS) || !defined(_PR_GLOBAL_THREADS_ONLY)) \
         && (!defined(AIX) || !defined(_PR_PTHREADS)) \
         && (!defined(OSF1) || !defined(_PR_PTHREADS)) \
         && (!defined(HPUX) || !defined(_PR_PTHREADS)) \
         && (!defined(IRIX) || !defined(_PR_PTHREADS)) \
         && (!defined(LINUX) || !defined(_PR_PTHREADS)) \
+	&& (!defined(RHAPSODY)) \
         && !defined(PURIFY) \
         && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
 #define _PR_OVERRIDE_MALLOC
 #endif
 
 /*************************************************************************
 * External machine-dependent code provided by each OS.                     *                                                                     *
 *************************************************************************/
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -27,16 +27,20 @@
 #include <Strings.h>
 #endif
 
 #ifdef XP_UNIX
 #ifdef USE_DLFCN
 #include <dlfcn.h>
 #elif defined(USE_HPSHL)
 #include <dl.h>
+#elif defined(USE_RLD)
+#include <fcntl.h>
+#include <streams/streams.h>
+#include <mach-o/rld.h>
 #endif
 
 /* Define this on systems which don't have it (AIX) */
 #ifndef RTLD_LAZY
 #define RTLD_LAZY RTLD_NOW
 #endif
 #endif /* XP_UNIX */
 
@@ -57,16 +61,19 @@ struct PRLibrary {
 #endif
 #ifdef XP_MAC
     CFragConnectionID		dlh;
 #endif
 
 #ifdef XP_UNIX
 #if defined(USE_HPSHL)
     shl_t			dlh;
+#elif defined(USE_RLD)
+    NXStream*			dlh;
+    int				rld_fd;
 #else
     void*			dlh;
 #endif 
 #endif 
 };
 
 static PRLibrary *pr_loadmap;
 static PRLibrary *pr_exe_loadmap;
@@ -93,27 +100,29 @@ static void DLLErrorInternal(PRIntn oser
 ** with a big hairy lock wrapped around it. Not the best of situations,
 ** but will eventually come up with the right answer.
 */
 {
     const char *error = NULL;
 #ifdef HAVE_DLL
 #	ifdef USE_DLFCN
 	    error = dlerror();  /* $$$ That'll be wrong some of the time - AOF */
-#	elif defined(USE_HPSHL)
+#	else
 #		ifdef HAVE_STRERROR
-		    error = strerror(oserr);  /* This should be okay */
+		    error = strerror(oserr);  /* this should be okay */
 #		else
 		    error = errno_string(oserr);
-#		endif /* HAVE_STRERROR */
-#	else
-	    error = errno_string(oserr);
+#		endif
 #	endif
 #else
+#  ifdef HAVE_STRERROR
+    error = strerror(oserr);
+#  else
     error = errno_string(oserr);
+#  endif /* HAVE_STRERROR */
 #endif /* HAVE_DLL */
     if (NULL != error)
         PR_SetErrorText(strlen(error), error);
 }  /* DLLErrorInternal */
 
 void _PR_InitLinker(void)
 {
 #ifndef XP_MAC
@@ -162,16 +171,18 @@ void _PR_InitLinker(void)
 	    fprintf(stderr, "failed to initialize shared libraries [%s]\n",
 		    error);
 		PR_DELETE(error);
 	    abort();/* XXX */
 	}
 #elif defined(USE_HPSHL)
 	h = NULL;
 	/* don't abort with this NULL */
+#elif defined(USE_RLD)
+	h = NULL; /* XXXX  toshok */
 #else
 #error no dll strategy
 #endif /* USE_DLFCN */
 
     lm = PR_NEWZAP(PRLibrary);
     if (lm) {
         lm->name = strdup("a.out");
     	lm->refCount = 1;
@@ -274,17 +285,17 @@ PR_GetLibraryPath()
 	if (p) {
 	    strcpy(p, ev);
 	}
 	ev = p;
 	}
 #endif
 
 #ifdef XP_UNIX
-#if defined USE_DLFCN
+#if defined USE_DLFCN || defined USE_RLD
     {
 	char *home;
 	char *local;
 	char *p;
 	int len;
 
 	ev = getenv("LD_LIBRARY_PATH");
 	if (!ev) {
@@ -621,16 +632,21 @@ PR_LoadLibrary(const char *name)
 #if defined(USE_DLFCN)
 	void *h = dlopen(name, RTLD_LAZY);
 #elif defined(USE_HPSHL)
     /*
      * Shared libraries built using aCC cannot be dynamically loaded
      * with BIND_DEFERRED, so we have to use the BIND_IMMEDIATE flag.
      */
     shl_t h = shl_load(name, BIND_IMMEDIATE | DYNAMIC_PATH, 0L);
+#elif defined(USE_RLD)
+    int fd = open(name, O_RDONLY);
+    NXStream *h = NXOpenFile(fd, NX_READONLY);
+
+    lm->rld_fd = fd;
 #else
 #error Configuration error
 #endif
 	if (!h) {
 	    PR_DELETE(lm);
 	    goto unlock;
 	}
 	lm->name = strdup(name);
@@ -687,16 +703,20 @@ PR_UnloadLibrary(PRLibrary *lib)
 	goto done;
     }
 #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_RLD)
+    result = rld_unload(lib->dlh);
+    NXClose(lib->dlh);
+    close(lib->rld_fd);
 #else
 #error Configuration error
 #endif
 #endif /* HAVE_DLL */
 #endif /* XP_UNIX */
 #ifdef XP_PC
     if (lib->dlh) {
         FreeLibrary((HINSTANCE)(lib->dlh));
@@ -797,16 +817,19 @@ pr_FindSymbolInLib(PRLibrary *lm, const 
 
 #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;
+#elif defined(USE_RLD)
+    if (rld_lookup(lm->dlh, name, (unsigned long*)&f) == -1)
+	f = NULL;
 #endif
 #endif /* HAVE_DLL */
 #endif /* XP_UNIX */
     if (f == NULL) {
         PR_SetError(PR_FIND_SYMBOL_ERROR, _MD_ERRNO());
         DLLErrorInternal(_MD_ERRNO());
     }
     return f;
--- a/pr/src/md/prosdep.c
+++ b/pr/src/md/prosdep.c
@@ -37,17 +37,17 @@ PRInt32 _pr_pageSize;
 */
 static void GetPageSize(void)
 {
 	PRInt32 pageSize;
 
     /* Get page size */
 #ifdef XP_UNIX
 #if defined SUNOS4 || defined LINUX || defined BSDI || defined AIX \
-	|| defined FREEBSD
+	|| defined FREEBSD || defined RHAPSODY
     _pr_pageSize = getpagesize();
 #elif defined(HPUX)
     /* I have no idea. Don't get me started. --Rob */
     _pr_pageSize = sysconf(_SC_PAGE_SIZE);
 #else
     _pr_pageSize = sysconf(_SC_PAGESIZE);
 #endif
 #endif /* XP_UNIX */
--- a/pr/src/md/unix/Makefile
+++ b/pr/src/md/unix/Makefile
@@ -76,16 +76,20 @@ LINUX_CSRCS = \
 UNIXWARE_CSRCS = \
 	unixware.c \
 	$(NULL)
 
 RELIANTUNIX_CSRCS = \
       reliantunix.c \
       $(NULL)
 
+RHAPSODY_CSRCS = \
+      rhapsody.c \
+      $(NULL)
+
 NEC_CSRCS = \
 	nec.c \
 	$(NULL)
 
 SONY_CSRCS = \
 	sony.c \
 	$(NULL)
 
@@ -141,16 +145,19 @@ ifeq ($(OS_ARCH),NEC)
 CSRCS += $(NEC_CSRCS)
 endif
 ifeq ($(OS_ARCH),NEWS-OS)
 CSRCS += $(SONY_CSRCS)
 endif
 ifeq ($(OS_ARCH),NCR)
 CSRCS += $(NCR_CSRCS)
 endif
+ifeq ($(OS_ARCH),Rhapsody)
+CSRCS += $(RHAPSODY_CSRCS)
+endif
 ifeq ($(OS_ARCH),SCO_SV)
 CSRCS += $(SCOOS_CSRCS)
 endif
 
 #
 # Some Unix platforms have an assembly language file.
 # E.g., AIX 3.2, Solaris (both sparc and x86).
 #
new file mode 100644
--- /dev/null
+++ b/pr/src/md/unix/darwin.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OSF1 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OSF1.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+#include <fcntl.h>
+
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+{
+    int i;
+    int rv;
+    int maxfd;
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+
+    if (timeout < 0 && timeout != -1) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    if (timeout == -1) {
+        tvp = NULL;
+    } else {
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000;
+        tvp = &tv;
+    }
+
+    maxfd = -1;
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    for (i = 0; i < nfds; i++) {
+	int osfd = filedes[i].fd;
+	int events = filedes[i].events;
+	PRBool fdHasEvent = PR_FALSE;
+
+	if (osfd < 0) {
+            continue;  /* Skip this osfd. */
+	}
+
+	/*
+	 * Map the native poll flags to nspr poll flags.
+	 *     POLLIN, POLLRDNORM  ===> PR_POLL_READ
+	 *     POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
+	 *     POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
+	 *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+	 *     are ignored.
+	 *
+	 * The output events POLLERR and POLLHUP are never turned on.
+	 * POLLNVAL may be turned on.
+	 */
+
+	if (events & (POLLIN | POLLRDNORM)) {
+	    FD_SET(osfd, &rd);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (events & (POLLOUT | POLLWRNORM)) {
+	    FD_SET(osfd, &wr);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (events & (POLLPRI | POLLRDBAND)) {
+	    FD_SET(osfd, &ex);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (fdHasEvent && osfd > maxfd) {
+	    maxfd = osfd;
+	}
+    }
+
+    rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
+
+    /* Compute poll results */
+    if (rv > 0) {
+	rv = 0;
+        for (i = 0; i < nfds; i++) {
+	    PRBool fdHasEvent = PR_FALSE;
+
+	    filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+	    if (FD_ISSET(filedes[i].fd, &rd)) {
+		if (filedes[i].events & POLLIN) {
+		    filedes[i].revents |= POLLIN;
+		}
+		if (filedes[i].events & POLLRDNORM) {
+		    filedes[i].revents |= POLLRDNORM;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (FD_ISSET(filedes[i].fd, &wr)) {
+		if (filedes[i].events & POLLOUT) {
+		    filedes[i].revents |= POLLOUT;
+		}
+		if (filedes[i].events & POLLWRNORM) {
+		    filedes[i].revents |= POLLWRNORM;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (FD_ISSET(filedes[i].fd, &ex)) {
+		if (filedes[i].events & POLLPRI) {
+		    filedes[i].revents |= POLLPRI;
+		}
+		if (filedes[i].events & POLLRDBAND) {
+		    filedes[i].revents |= POLLRDBAND;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (fdHasEvent) {
+		rv++;
+            }
+        }
+	PR_ASSERT(rv > 0);
+    } else if (rv == -1 && errno == EBADF) {
+	rv = 0;
+        for (i = 0; i < nfds; i++) {
+	    filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+	    if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
+		filedes[i].revents = POLLNVAL;
+		rv++;
+	    }
+        }
+	PR_ASSERT(rv > 0);
+    }
+    PR_ASSERT(-1 != timeout || rv != 0);
+
+    return rv;
+}
+#endif /* _PR_NEED_FAKE_POLL */
--- a/pr/src/md/unix/objs.mk
+++ b/pr/src/md/unix/objs.mk
@@ -68,16 +68,20 @@ LINUX_CSRCS = \
 UNIXWARE_CSRCS = \
 	unixware.c \
 	$(NULL)
 
 RELIANTUNIX_CSRCS = \
 	reliantunix.c \
 	$(NULL)
 
+RHAPSODY_CSRCS = \
+	rhapsody.c \
+	$(NULL)
+
 NEC_CSRCS = \
 	nec.c \
 	$(NULL)
 
 SONY_CSRCS = \
 	sony.c \
 	$(NULL)
 
@@ -125,16 +129,19 @@ ifeq ($(OS_ARCH),Linux)
 CSRCS += $(LINUX_CSRCS)
 endif
 ifeq ($(OS_ARCH),UNIXWARE)
 CSRCS += $(UNIXWARE_CSRCS)
 endif
 ifeq ($(OS_ARCH),ReliantUNIX)
 CSRCS += $(RELIANTUNIX_CSRCS)
 endif
+ifeq ($(OS_ARCH),Rhapsody)
+CSRCS += $(RHAPSODY_CSRCS)
+endif
 ifeq ($(OS_ARCH),NEC)
 CSRCS += $(NEC_CSRCS)
 endif
 ifeq ($(OS_ARCH),NEWS-OS)
 CSRCS += $(SONY_CSRCS)
 endif
 ifeq ($(OS_ARCH),NCR)
 CSRCS += $(NCR_CSRCS)
new file mode 100644
--- /dev/null
+++ b/pr/src/md/unix/rhapsody.c
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.0 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "primpl.h"
+
+#include <signal.h>
+
+void _MD_EarlyInit(void)
+{
+    /*
+     * Ignore FPE because coercion of a NaN to an int causes SIGFPE
+     * to be raised.
+     */
+    struct sigaction act;
+
+    act.sa_handler = SIG_IGN;
+    sigemptyset(&act.sa_mask);
+    act.sa_flags = SA_RESTART;
+    sigaction(SIGFPE, &act, 0);
+}
+
+PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
+{
+#ifndef _PR_PTHREADS
+    if (isCurrent) {
+	(void) sigsetjmp(CONTEXT(t), 1);
+    }
+    *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
+    return (PRWord *) CONTEXT(t);
+#else
+	*np = 0;
+	return NULL;
+#endif
+}
+
+#ifndef _PR_PTHREADS
+void
+_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
+{
+    return;
+}
+
+PRStatus
+_MD_InitializeThread(PRThread *thread)
+{
+	return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
+{
+    PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    _PR_MD_SWITCH_CONTEXT(thread);
+    return PR_SUCCESS;
+}
+
+PRStatus
+_MD_WAKEUP_WAITER(PRThread *thread)
+{
+    if (thread) {
+	PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
+    }
+    return PR_SUCCESS;
+}
+
+/* These functions should not be called for OSF1 */
+void
+_MD_YIELD(void)
+{
+    PR_NOT_REACHED("_MD_YIELD should not be called for OSF1.");
+}
+
+PRStatus
+_MD_CREATE_THREAD(
+    PRThread *thread,
+    void (*start) (void *),
+    PRThreadPriority priority,
+    PRThreadScope scope,
+    PRThreadState state,
+    PRUint32 stackSize)
+{
+    PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for OSF1.");
+	return PR_FAILURE;
+}
+#endif /* ! _PR_PTHREADS */
+
+#if defined(_PR_NEED_FAKE_POLL)
+
+#include <fcntl.h>
+
+int poll(struct pollfd *filedes, unsigned long nfds, int timeout)
+{
+    int i;
+    int rv;
+    int maxfd;
+    fd_set rd, wr, ex;
+    struct timeval tv, *tvp;
+
+    if (timeout < 0 && timeout != -1) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    if (timeout == -1) {
+        tvp = NULL;
+    } else {
+	tv.tv_sec = timeout / 1000;
+	tv.tv_usec = (timeout % 1000) * 1000;
+        tvp = &tv;
+    }
+
+    maxfd = -1;
+    FD_ZERO(&rd);
+    FD_ZERO(&wr);
+    FD_ZERO(&ex);
+
+    for (i = 0; i < nfds; i++) {
+	int osfd = filedes[i].fd;
+	int events = filedes[i].events;
+	PRBool fdHasEvent = PR_FALSE;
+
+	if (osfd < 0) {
+            continue;  /* Skip this osfd. */
+	}
+
+	/*
+	 * Map the native poll flags to nspr poll flags.
+	 *     POLLIN, POLLRDNORM  ===> PR_POLL_READ
+	 *     POLLOUT, POLLWRNORM ===> PR_POLL_WRITE
+	 *     POLLPRI, POLLRDBAND ===> PR_POLL_EXCEPTION
+	 *     POLLNORM, POLLWRBAND (and POLLMSG on some platforms)
+	 *     are ignored.
+	 *
+	 * The output events POLLERR and POLLHUP are never turned on.
+	 * POLLNVAL may be turned on.
+	 */
+
+	if (events & (POLLIN | POLLRDNORM)) {
+	    FD_SET(osfd, &rd);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (events & (POLLOUT | POLLWRNORM)) {
+	    FD_SET(osfd, &wr);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (events & (POLLPRI | POLLRDBAND)) {
+	    FD_SET(osfd, &ex);
+	    fdHasEvent = PR_TRUE;
+	}
+	if (fdHasEvent && osfd > maxfd) {
+	    maxfd = osfd;
+	}
+    }
+
+    rv = select(maxfd + 1, &rd, &wr, &ex, tvp);
+
+    /* Compute poll results */
+    if (rv > 0) {
+	rv = 0;
+        for (i = 0; i < nfds; i++) {
+	    PRBool fdHasEvent = PR_FALSE;
+
+	    filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+	    if (FD_ISSET(filedes[i].fd, &rd)) {
+		if (filedes[i].events & POLLIN) {
+		    filedes[i].revents |= POLLIN;
+		}
+		if (filedes[i].events & POLLRDNORM) {
+		    filedes[i].revents |= POLLRDNORM;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (FD_ISSET(filedes[i].fd, &wr)) {
+		if (filedes[i].events & POLLOUT) {
+		    filedes[i].revents |= POLLOUT;
+		}
+		if (filedes[i].events & POLLWRNORM) {
+		    filedes[i].revents |= POLLWRNORM;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (FD_ISSET(filedes[i].fd, &ex)) {
+		if (filedes[i].events & POLLPRI) {
+		    filedes[i].revents |= POLLPRI;
+		}
+		if (filedes[i].events & POLLRDBAND) {
+		    filedes[i].revents |= POLLRDBAND;
+		}
+		fdHasEvent = PR_TRUE;
+	    }
+	    if (fdHasEvent) {
+		rv++;
+            }
+        }
+	PR_ASSERT(rv > 0);
+    } else if (rv == -1 && errno == EBADF) {
+	rv = 0;
+        for (i = 0; i < nfds; i++) {
+	    filedes[i].revents = 0;
+            if (filedes[i].fd < 0) {
+                continue;
+            }
+	    if (fcntl(filedes[i].fd, F_GETFL, 0) == -1) {
+		filedes[i].revents = POLLNVAL;
+		rv++;
+	    }
+        }
+	PR_ASSERT(rv > 0);
+    }
+    PR_ASSERT(-1 != timeout || rv != 0);
+
+    return rv;
+}
+#endif /* _PR_NEED_FAKE_POLL */
--- a/pr/src/md/unix/unix.c
+++ b/pr/src/md/unix/unix.c
@@ -39,17 +39,17 @@
  * PRInt32* pointer to a _PRSockLen_t* pointer.
  */
 #if defined(IRIX) || defined(HPUX) || defined(OSF1) || defined(SOLARIS) \
     || defined(AIX4_1) || defined(LINUX) || defined(SONY) \
     || defined(BSDI) || defined(SCO) || defined(NEC) || defined(SNI) \
     || defined(SUNOS4)
 #define _PRSockLen_t int
 #elif (defined(AIX) && !defined(AIX4_1)) || defined(FREEBSD) \
-    || defined(UNIXWARE)
+    || defined(UNIXWARE) || defined(RHAPSODY)
 #define _PRSockLen_t size_t
 #else
 #error "Cannot determine architecture"
 #endif
 
 /*
 ** Global lock variable used to bracket calls into rusty libraries that
 ** aren't thread safe (like libc, libX, etc).
@@ -1193,17 +1193,17 @@ PRInt32 _MD_socketpair(int af, int type,
 
 PRStatus _MD_getsockname(PRFileDesc *fd, PRNetAddr *addr,
 												PRUint32 *addrlen)
 {
     PRInt32 rv, err;
 
     rv = getsockname(fd->secret->md.osfd,
             (struct sockaddr *) addr, (_PRSockLen_t *)addrlen);
-#ifdef AIX
+#if defined( AIX ) || defined( RHAPSODY )
     if (rv == 0) {
         /* mask off the first byte of struct sockaddr (the length field) */
         if (addr) {
             addr->inet.family &= 0x00ff;
         }
     }
 #endif
     if (rv < 0) {
@@ -2337,17 +2337,17 @@ PRInt32 _MD_open(const char *name, PRInt
 		osflags = O_RDONLY;
 	}
 
 	if (flags & PR_APPEND)
 		osflags |= O_APPEND;
 	if (flags & PR_TRUNCATE)
 		osflags |= O_TRUNC;
 	if (flags & PR_SYNC) {
-#if defined(FREEBSD)
+#if defined(FREEBSD) || defined(RHAPSODY)
 		osflags |= O_FSYNC;
 #else
 		osflags |= O_SYNC;
 #endif
 	}
 
     /*
     ** On creations we hold the 'create' lock in order to enforce
--- a/pr/src/md/unix/unix_errors.c
+++ b/pr/src/md/unix/unix_errors.c
@@ -155,17 +155,17 @@ void _MD_unix_map_unlink_error(int err)
 			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
 			break;
 		case EPERM:
 			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
 			break;
 		case EROFS:
 			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
 			break;
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 #endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
@@ -180,17 +180,17 @@ void _MD_unix_map_stat_error(int err)
 			break;
 		case EFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
 		case EINTR:
 			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
 			break;
 		case ETIMEDOUT:
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 #endif
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 		case ELOOP:
 			PR_SetError(PR_LOOP_ERROR, err);
 			break;
@@ -273,17 +273,17 @@ void _MD_unix_map_rename_error(int err)
 			PR_SetError(PR_IO_ERROR, err);
 			break;
 		case EISDIR:
 			PR_SetError(PR_IS_DIRECTORY_ERROR, err);
 			break;
 		case ELOOP:
 			PR_SetError(PR_LOOP_ERROR, err);
 			break;
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 #endif
 		case ENAMETOOLONG:
 			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
 			break;
@@ -324,17 +324,17 @@ void _MD_unix_map_access_error(int err)
 			PR_SetError(PR_PENDING_INTERRUPT_ERROR, err);
 			break;
 		case EINVAL:
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
 			break;
 		case ELOOP:
 			PR_SetError(PR_LOOP_ERROR, err);
 			break;
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 #endif
 		case ETIMEDOUT:
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 		case ENAMETOOLONG:
 			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
@@ -390,17 +390,17 @@ void _MD_unix_map_mkdir_error(int err)
 #ifdef EDQUOT
 		case EDQUOT:
 			PR_SetError(PR_NO_DEVICE_SPACE_ERROR, err);
 			break;
 #endif
 		case EIO:
 			PR_SetError(PR_IO_ERROR, err);
 			break;
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 #endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
@@ -427,17 +427,17 @@ void _MD_unix_map_rmdir_error(int err)
 			PR_SetError(PR_DIRECTORY_NOT_EMPTY_ERROR, err);
 			break;
 		case EIO:
 			PR_SetError(PR_IO_ERROR, err);
 			break;
 		case ELOOP:
 			PR_SetError(PR_LOOP_ERROR, err);
 			break;
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 #endif
 		case ETIMEDOUT:
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 		case ENAMETOOLONG:
 			PR_SetError(PR_NAME_TOO_LONG_ERROR, err);
@@ -1340,17 +1340,17 @@ void _MD_unix_map_open_error(int err)
 			break;
 		case ENOTDIR:
 			PR_SetError(PR_NOT_DIRECTORY_ERROR, err);
 			break;
 		case EPERM:
 			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
 			break;
 		case ETIMEDOUT:
-#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(OSF1) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 		case EMULTIHOP:
 		case ENOLINK:
 #endif
 			PR_SetError(PR_REMOTE_FILE_ERROR, err);
 			break;
 		case EROFS:
 			PR_SetError(PR_READ_ONLY_FILESYSTEM_ERROR, err);
 			break;
--- a/pr/src/md/unix/uxwrap.c
+++ b/pr/src/md/unix/uxwrap.c
@@ -291,20 +291,20 @@ int select(int width, fd_set *rd, fd_set
     PR_ASSERT(tv || retVal != 0);
     PR_LOG(_pr_io_lm, PR_LOG_MIN, ("select returns %d", retVal));
     PR_DELETE(pollset);
 
     return retVal;
 }
 
 /*
- * Linux, BSDI, and FreeBSD don't have poll()
+ * Linux, BSDI, Rhapsody and FreeBSD don't have poll()
  */
 
-#if !defined(LINUX) && !defined(FREEBSD) && !defined(BSDI)
+#if !defined(LINUX) && !defined(FREEBSD) && !defined(BSDI) && !defined(RHAPSODY)
 
 /*
  *-----------------------------------------------------------------------
  * poll() --
  *
  * RETURN VALUES: 
  *     -1:  fails, errno indicates the error.
  *      0:  timed out, the revents bitmasks are not set.
--- a/pr/src/memory/prseg.c
+++ b/pr/src/memory/prseg.c
@@ -144,32 +144,34 @@ PR_IMPLEMENT(PRUint32) PR_GrowSegment(PR
 ** it.
 */
 PR_IMPLEMENT(void) PR_MapSegment(PRSegment *seg, PRSegmentAccess how)
 {
     if (seg->access == how) return;
     seg->access = how;
 
 #ifdef XP_UNIX
+#ifndef RHAPSODY
     if (seg->flags & _PR_SEG_VM) {
 	int prot;
 	switch (how) {
 	  case PR_SEGMENT_NONE:
 	    prot = PROT_NONE;
 	    break;
 	  case PR_SEGMENT_RDONLY:
 	    prot = PROT_READ;
 	    break;
 	  case PR_SEGMENT_RDWR:
 	    prot = PROT_READ|PROT_WRITE;
 	    break;
 	}
 	(void) mprotect(seg->vaddr, seg->size, prot);
     }
 #endif
+#endif
 }
 
 /*
 ** Return the size of the segment
 */
 PR_IMPLEMENT(size_t) PR_GetSegmentSize(PRSegment *seg)
 {
     return seg->size;