Enable OS/2 builds with IBM's compiler (Visualage) and gcc port of OS/2 (emx).
authorsrinivas%netscape.com
Thu, 19 Nov 1998 22:20:31 +0000
changeset 324 df0c936ae18716268c28f27461a45aeb55e5da90
parent 321 6efb36669dfb3114d170e4047ad91aeb49a11b7d
child 325 02caf72026bcb7893414dbcffc073c7b7253fb58
push idunknown
push userunknown
push dateunknown
Enable OS/2 builds with IBM's compiler (Visualage) and gcc port of OS/2 (emx). Checkin for Eric Olson <Eric.Olson@Sympatico.CA> and Henry <sobotka@axess.com>.
config/Makefile
config/OS2.mk
config/arch.mk
config/now.c
config/rules.mk
lib/ds/Makefile
lib/ds/plevent.c
lib/ds/plevent.h
lib/ds/plhash.h
lib/libc/src/Makefile
pr/include/md/Makefile
pr/include/md/_os2.h
pr/include/md/_os2_errors.h
pr/include/md/_pcos.h
pr/include/prtypes.h
pr/src/Makefile
pr/src/io/prlog.c
pr/src/io/prsocket.c
pr/src/linking/prlink.c
pr/src/md/os2/os2_errors.c
pr/src/md/os2/os2gc.c
pr/src/md/os2/os2inrval.c
pr/src/md/os2/os2io.c
pr/src/md/os2/os2misc.c
pr/src/md/os2/os2poll.c
pr/src/md/os2/os2sock.c
pr/src/md/os2/os2thred.c
pr/src/misc/prnetdb.c
pr/src/misc/prsystem.c
pr/src/misc/prtime.c
pr/tests/Makefile
pr/tests/attach.c
pr/tests/ipv6.c
pr/tests/op_filok.c
pr/tests/sel_spd.c
pr/tests/select2.c
pr/tests/servr_kk.c
pr/tests/servr_ku.c
pr/tests/servr_uk.c
pr/tests/servr_uu.c
pr/tests/sleep.c
pr/tests/stat.c
pr/tests/strod.c
pr/tests/testfile.c
pr/tests/tmocon.c
--- a/config/Makefile
+++ b/config/Makefile
@@ -56,16 +56,25 @@ ifeq ($(OS_ARCH), IRIX)
 endif
 
 ifeq ($(OS_ARCH), HP-UX)
     ifeq ($(USE_64),1)
         XLDOPTS += +DD64
     endif
 endif
 
+ifdef XP_OS2_EMX
+XCFLAGS = $(OS_EXE_CFLAGS)
+XLDOPTS = -Zlinker /PM:VIO
+endif
+
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+OS_CFLAGS = $(OS_EXE_CFLAGS)
+endif
+
 include $(MOD_DEPTH)/config/rules.mk
 
 PROGS	= $(OBJDIR)/now$(PROG_SUFFIX)
 
 ifeq ($(OS_ARCH),WINNT)
 TARGETS = $(PROGS)
 else
 PROGS	+= $(OBJDIR)/nsinstall$(PROG_SUFFIX)
@@ -76,10 +85,13 @@ endif
 define MAKE_OBJDIR
 if test ! -d $(@D); then rm -rf $(@D); mkdir $(@D); fi
 endef
 
 export:: $(TARGETS)
 
 $(OBJDIR)/%$(PROG_SUFFIX): $(OBJDIR)/%.$(OBJ_SUFFIX)
 	@$(MAKE_OBJDIR)
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+	$(LINK) $(EXEFLAGS) $<
+else
 	$(CC) $(XCFLAGS) $< $(XLDOPTS) -o $@
-
+endif
--- a/config/OS2.mk
+++ b/config/OS2.mk
@@ -21,67 +21,124 @@
 # OS_CFLAGS is the command line options for the compiler when
 #   building the .DLL object files.
 # OS_EXE_CFLAGS is the command line options for the compiler
 #   when building the .EXE object files; this is for the test
 #   programs.
 # the macro OS_CFLAGS is set to OS_EXE_CFLAGS inside of the
 #   makefile for the pr/tests directory. ... Hack.
 
+# Specify toolset.  Default to EMX.
+ifeq ($(MOZ_OS2_TOOLS),VACPP)
+XP_OS2_VACPP = 1
+else
+ifeq ($(MOZ_OS2_TOOLS),PGCC)
+XP_OS2_EMX   = 1
+else
+MOZ_OS2_TOOLS = EMX
+XP_OS2_EMX   = 1
+endif
+endif
 
 #
 # On OS/2 we proudly support gbash...
 #
 SHELL = GBASH.EXE
 
 CC			= icc -q -DXP_OS2 -N10
 CCC			= icc -q -DXP_OS2 -DOS2=4 -N10
-LINK			= flipper ilink
-AR			= flipper ilibo //noignorecase //nologo $@
-RANLIB = echo
-BSDECHO = echo
-NSINSTALL = nsinstall
-INSTALL	= $(NSINSTALL)
-MAKE_OBJDIR = mkdir $(OBJDIR)
-IMPLIB = flipper implib -nologo -noignorecase
-FILTER = flipper cppfilt -q
-RC = rc.exe
+LINK			= ilink
+AR			= ilib /noignorecase /nologo $(subst /,\\,$@)
+RANLIB 			= @echo RANLIB
+BSDECHO 		= @echo BSDECHO
+NSINSTALL 		= nsinstall
+INSTALL			= $(NSINSTALL)
+MAKE_OBJDIR 		= if test ! -d $(OBJDIR); then mkdir $(OBJDIR); fi
+IMPLIB 			= implib -nologo -noignorecase
+FILTER 			= cppfilt -b -p -q
+RC 			= rc.exe
 
 GARBAGE =
 
-XP_DEFINE = -DXP_PC
-OBJ_SUFFIX = obj
-LIB_SUFFIX = lib
-DLL_SUFFIX = dll
+XP_DEFINE 		= -DXP_PC
+LIB_SUFFIX 		= lib
+DLL_SUFFIX 		= dll
+OBJ_SUFFIX		= obj
 
-OS_CFLAGS     = -I. -W3 -gm -gd+ -sd- -su4 -ge-
-OS_EXE_CFLAGS = -I. -W3 -gm -gd+ -sd- -su4 
-AR_EXTRA_ARGS = ,,
+OS_CFLAGS     		= -W3 -Wcnd- -gm -gd+ -sd- -su4 -ge-
+OS_EXE_CFLAGS 		= -W3 -Wcnd- -gm -gd+ -sd- -su4 
+AR_EXTRA_ARGS 		= ,,
 
 ifdef BUILD_OPT
-OPTIMIZER	= -O+ -Oi 
-DEFINES = -UDEBUG -U_DEBUG -DNDEBUG
-DLLFLAGS	= -DLL -OUT:$@ -MAP:$(@:.dll=.map)
-OBJDIR_TAG = _OPT
+OPTIMIZER		= -O+ -Oi 
+DEFINES 		= -UDEBUG -U_DEBUG -DNDEBUG
+DLLFLAGS		= -DLL -OUT:$@ -MAP:$(@:.dll=.map)
+EXEFLAGS    		= -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
+OBJDIR_TAG 		= _OPT
 else
-OPTIMIZER	= -Ti+
-DEFINES = -DDEBUG -D_DEBUG -UNDEBUG
-DLLFLAGS	= -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map)
-OBJDIR_TAG = _DBG
-LDFLAGS = -DEBUG 
+OPTIMIZER		= -Ti+ -DE
+DEFINES 		= -DDEBUG -D_DEBUG -DDEBUGPRINTS
+DLLFLAGS		= -DEBUG -DLL -OUT:$@ -MAP:$(@:.dll=.map)
+EXEFLAGS    		= -DEBUG -PMTYPE:VIO -OUT:$@ -MAP:$(@:.exe=.map) -nologo -NOE
+OBJDIR_TAG 		= _DBG
+LDFLAGS 		= -DEBUG 
+endif
+
+DEFINES += -DOS2=4
+DEFINES += -D_X86_
+DEFINES += -D_PR_GLOBAL_THREADS_ONLY -DBSD_SELECT
+
+# Name of the binary code directories
+ifdef MOZ_LITE
+OBJDIR_NAME 		= $(subst OS2,NAV,$(OS_CONFIG))_$(MOZ_OS2_TOOLS)$(OBJDIR_TAG).OBJ
+else
+OBJDIR_NAME 		= $(OS_CONFIG)_$(MOZ_OS2_TOOLS)$(OBJDIR_TAG).OBJ
 endif
 
-DEFINES += -DOS2=4 -DBSD_SELECT
-DEFINES += -D_X86_
-DEFINES += -D_PR_GLOBAL_THREADS_ONLY
+OS_DLLFLAGS 		= -nologo -DLL -FREE -NOE
+
+ifdef XP_OS2_VACPP
+
+OS_LIBS 		= so32dll.lib tcp32dll.lib
+
+DEFINES += -DXP_OS2_VACPP
 
-# Name of the binary code directories
-ifeq ($(CPU_ARCH),x86)
-ifdef MOZ_LITE
-OBJDIR_NAME = $(subst OS2,NAV,$(OS_CONFIG))$(OBJDIR_TAG).OBJ
 else
-OBJDIR_NAME = $(OS_CONFIG)$(OBJDIR_TAG).OBJ
-endif
+CC			= gcc
+CCC			= gcc
+LINK			= gcc
+RC 			= rc.exe
+FILTER  		= emxexp
+IMPLIB  		= emximp -o
+
+# Determine which object format to use.  Two choices:
+# a.out and omf.  We default to omf.
+ifeq ($(MOZ_OS2_EMX_OBJECTFORMAT), A.OUT)
+AR      	= ar -q $@
+LIB_SUFFIX	= a
 else
-OBJDIR_NAME = $(OS_CONFIG)$(CPU_ARCH)$(OBJDIR_TAG).OBJ
+OMF_FLAG 	= -Zomf
+AR		= emxomfar r $@
+LIB_SUFFIX	= lib
 endif
 
-OS_DLLFLAGS = -nologo -DLL -FREE -NOE
+OS_LIBS     		= -lsocket -lemxio
+
+DEFINES += -DXP_OS2 -DXP_OS2_EMX  -DOS2EMX_PLAIN_CHAR #-DHAVE_SIGNED_CHAR
+
+OS_CFLAGS     		= $(OMF_FLAG) -Wall -Wno-unused -Zmtd
+OS_EXE_CFLAGS 		= $(OMF_FLAG) -Wall -Wno-unused -Zmtd
+OS_DLLFLAGS 		= $(OMF_FLAG) -Zmt -Zdll -Zcrtdll -o $@
+
+ifdef BUILD_OPT
+OPTIMIZER		= -O3
+DLLFLAGS		= 
+EXEFLAGS    		= -Zmtd -o $@
+else
+OPTIMIZER		= -g
+DLLFLAGS		= -g
+EXEFLAGS		= -g $(OMF_FLAG) -Zmtd -L$(DIST)/lib -o $@
+endif
+
+AR_EXTRA_ARGS 		=
+endif
+
+
--- a/config/arch.mk
+++ b/config/arch.mk
@@ -96,16 +96,25 @@ ifeq ($(OS_ARCH)$(OS_RELEASE),OSF1V4.0)
 	ifeq ($(OS_VERSION),564)
 		OS_RELEASE := V4.0B
 	endif
 	ifeq ($(OS_VERSION),878)
 		OS_RELEASE := V4.0D
 	endif
 endif
 
+#
+# Handle uname variants for OS/2.
+#
+
+ifeq ($(OS_ARCH),OS_2)
+	OS_ARCH		:= OS2
+	OS_RELEASE	:= 4.0
+endif
+
 #######################################################################
 # Master "Core Components" macros for getting the OS target           #
 #######################################################################
 
 #
 # Note: OS_TARGET should be specified on the command line for gmake.
 # When OS_TARGET=WIN95 is specified, then a Windows 95 target is built.
 # The difference between the Win95 target and the WinNT target is that
@@ -130,27 +139,31 @@ endif
 ifeq ($(OS_ARCH),WIN95)
 	OS_ARCH   := WINNT
 	OS_TARGET := WIN95
 endif
 ifeq ($(OS_ARCH),Windows_95)
 	OS_ARCH   := Windows_NT
 	OS_TARGET := WIN95
 endif
-ifeq ($(OS_ARCH), OS2)
+ifeq ($(OS_ARCH),OS2)
 	OS_ARCH   := WINNT
 	OS_TARGET := OS2
 endif
 
 #
 # On WIN32, we also define the variable CPU_ARCH.
 #
 
 ifeq ($(OS_ARCH), WINNT)
-	CPU_ARCH := $(shell uname -p)
+	ifneq ($(subst /,_,$(shell uname -s)),OS_2)
+		CPU_ARCH := $(shell uname -p)
+	else
+		CPU_ARCH := $(shell uname -m)
+	endif
 	ifeq ($(CPU_ARCH),I386)
 		CPU_ARCH = x86
 	endif
 else
 #
 # If uname -s returns "Windows_NT", we assume that we are using
 # the uname.exe in MKS toolkit.
 #
--- a/config/now.c
+++ b/config/now.c
@@ -14,19 +14,19 @@
  * 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)
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
 #include <sys/time.h>
-#elif defined(WIN32)
+#elif defined(WIN32) || defined(XP_OS2_VACPP)
 #include <sys/timeb.h>
 #else
 #error "Architecture not supported"
 #endif
 
 
 int main(int argc, char **argv)
 {
@@ -36,39 +36,67 @@ 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)
+#elif defined(XP_UNIX) || defined(XP_OS2_EMX)
     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);
 #else
     fprintf(stdout, "%lld", now);
 #endif
 
 #elif defined(WIN32)
     __int64 now;
+    long long now;
     struct timeb b;
     ftime(&b);
     now = b.time;
     now *= 1000000;
     now += (1000 * b.millitm);
     fprintf(stdout, "%I64d", now);
+
+#elif defined(XP_OS2_VACPP)
+/* no long long or i64 so we use a string */
+#include <string.h>
+  char buf[24];
+  char tbuf[7];
+  time_t now;
+  long mtime;
+  int i;
+
+  struct timeb b;
+  ftime(&b);
+  now = b.time;
+  _ltoa(now, buf, 10);
+
+  mtime = b.millitm * 1000;
+  if (mtime == 0){
+    ++now;
+    strcat(buf, "000000");
+  } else {
+     _ltoa(mtime, tbuf, 10);
+     for (i = strlen(tbuf); i < 6; ++i)
+       strcat(buf, "0");
+     strcat(buf, tbuf);
+  }
+  fprintf(stdout, "%s", buf);
+
 #else
 #error "Architecture not supported"
 #endif
 
     return 0;
 }  /* main */
 
 /* now.c */
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -67,23 +67,23 @@ endif
 ifdef LIBRARY_NAME
 ifeq ($(OS_ARCH), WINNT)
 
 #
 # Win16 and OS/2 require library names conforming to the 8.3 rule.
 # other platforms do not.
 #
 ifeq (,$(filter-out WIN16 OS2,$(OS_TARGET)))
-LIBRARY		= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.lib
-SHARED_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
-IMPORT_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
+LIBRARY		= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
 else
-LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.lib
-SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
-IMPORT_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
+LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_s.$(LIB_SUFFIX)
+SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(DLL_SUFFIX)
+IMPORT_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
 endif
 
 else
 
 LIBRARY		= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION).$(LIB_SUFFIX)
 ifeq ($(OS_ARCH)$(OS_RELEASE), AIX4.1)
 SHARED_LIBRARY	= $(OBJDIR)/lib$(LIBRARY_NAME)$(LIBRARY_VERSION)_shr.a
 else
@@ -230,17 +230,21 @@ ifeq ($(OS_ARCH),WINNT)
 	$(CC) $(OBJS) -Fe$@ -link $(LDFLAGS) $(OS_LIBS) $(EXTRA_LIBS)
 else
 	$(CC) -o $@ $(CFLAGS) $(OBJS) $(LDFLAGS)
 endif
 
 $(LIBRARY): $(OBJS)
 	@$(MAKE_OBJDIR)
 	rm -f $@
+ifdef XP_OS2_VACPP
+	$(AR) $(subst /,\\,$(OBJS)) $(AR_EXTRA_ARGS)
+else
 	$(AR) $(OBJS) $(AR_EXTRA_ARGS)
+endif
 	$(RANLIB) $@
 
 ifeq ($(OS_TARGET), WIN16)
 $(IMPORT_LIBRARY): $(SHARED_LIBRARY)
 	wlib $(OS_LIB_FLAGS) $@ +$(SHARED_LIBRARY)
 endif
 
 ifeq ($(OS_TARGET), OS2)
@@ -280,18 +284,18 @@ ifeq ($(OS_TARGET), WIN16)
 else
 ifeq ($(OS_TARGET), OS2)
 # append ( >> ) doesn't seem to be working under OS/2 gmake. Run through OS/2 shell instead.	
 	@cmd /C "echo LIBRARY $(notdir $(basename $(SHARED_LIBRARY))) INITINSTANCE TERMINSTANCE >$@.def"
 	@cmd /C "echo PROTMODE >>$@.def"
 	@cmd /C "echo CODE    LOADONCALL MOVEABLE DISCARDABLE >>$@.def"
 	@cmd /C "echo DATA    PRELOAD MOVEABLE MULTIPLE NONSHARED >>$@.def"	
 	@cmd /C "echo EXPORTS >>$@.def"
-	@cmd /C "$(FILTER) -B -P $(LIBRARY) >> $@.def"
-	$(LINK_DLL) -MAP $(DLLBASE) $(OS_LIBS) $(EXTRA_LIBS) $(OBJS) $@.def
+	@cmd /C "$(FILTER) $(LIBRARY) >> $@.def"
+	$(LINK_DLL) $(DLLBASE) $(OBJS) $(OS_LIBS) $(EXTRA_LIBS) $@.def
 else
 	$(LINK_DLL) -MAP $(DLLBASE) $(OS_LIBS) $(EXTRA_LIBS) $(OBJS)
 endif
 endif
 else
 	$(MKSHLIB) -o $@ $(OBJS) $(EXTRA_LIBS) $(OS_LIBS)
 endif
 endif
@@ -312,34 +316,40 @@ else
 	$(RC) -Fo$(RES) $(RESNAME)
 endif
 	@echo $(RES) finished
 endif
 
 $(OBJDIR)/%.$(OBJ_SUFFIX): %.cpp
 	@$(MAKE_OBJDIR)
 ifeq ($(OS_ARCH), WINNT)
+ifndef XP_OS2_EMX
 	$(CCC) -Fo$@ -c $(CCCFLAGS) $<
 else
-	$(CCC) -o $@ -c $(CCCFLAGS) $< 
+	$(CCC) -o $@ -c $(CFLAGS) $< 
+endif
 endif
 
 WCCFLAGS1 = $(subst /,\\,$(CFLAGS))
 WCCFLAGS2 = $(subst -I,-i=,$(WCCFLAGS1))
 WCCFLAGS3 = $(subst -D,-d,$(WCCFLAGS2))
 $(OBJDIR)/%.$(OBJ_SUFFIX): %.c
 	@$(MAKE_OBJDIR)
 ifeq ($(OS_ARCH), WINNT)
 ifeq ($(OS_TARGET), WIN16)
 #	$(MOD_DEPTH)/config/w16opt $(WCCFLAGS3)
 	echo $(WCCFLAGS3) >w16wccf
 	$(CC) -zq -fo$(OBJDIR)\\$*.$(OBJ_SUFFIX)  @w16wccf $*.c
 	rm w16wccf
 else
+ifndef XP_OS2_EMX
 	$(CC) -Fo$@ -c $(CFLAGS) $*.c
+else
+	$(CC) -o $@ -c $(CFLAGS) $*.c
+endif
 endif
 else
 	$(CC) -o $@ -c $(CFLAGS) $*.c
 endif
 
 $(OBJDIR)/%.$(OBJ_SUFFIX): %.s
 	@$(MAKE_OBJDIR)
 	$(AS) -o $@ $(ASFLAGS) -c $*.s
--- a/lib/ds/Makefile
+++ b/lib/ds/Makefile
@@ -41,17 +41,21 @@ HEADERS = \
 	plarena.h \
 	plevent.h \
 	plhash.h \
 	$(NULL)
 
 ifeq ($(OS_ARCH), WINNT)
 ifeq (,$(filter-out WIN16 OS2,$(OS_TARGET)))
 # OS_CFLAGS = $(OS_EXE_CFLAGS)
-EXTRA_LIBS = $(DIST)/lib/nspr$(MOD_VERSION).lib
+ifdef XP_OS2_EMX
+EXTRA_LIBS = -L$(DIST)/lib -lnspr$(MOD_VERSION)
+else
+EXTRA_LIBS = $(DIST)/lib/nspr$(MOD_VERSION).$(LIB_SUFFIX)
+endif
 else
 DLLBASE=/BASE:0x30000000
 RES=$(OBJDIR)/ds.res
 RESNAME=$(MOD_DEPTH)/pr/src/nspr.rc
 OS_LIBS = user32.lib
 EXTRA_LIBS = $(DIST)/lib/libnspr$(MOD_VERSION).lib
 
 ifdef MOZ_DEBUG
--- a/lib/ds/plevent.c
+++ b/lib/ds/plevent.c
@@ -10,24 +10,32 @@
  * 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.
  */
+#if defined(XP_OS2)
+#define INCL_DOSEXCEPTIONS
+#define INCL_WIN
+#include <os2.h>
+#define PostMessage   WinPostMsg
+#define DefWindowProc WinDefWindowProc
+typedef MPARAM WPARAM,LPARAM;
+#endif
 #include "plevent.h"
 #include "prmem.h"
 #include "prcmon.h"
 #include "prlog.h"
 #if !defined(WIN32)
 #include <errno.h>
 #include <stddef.h>
-#if !defined(OS2)
+#if !defined(XP_OS2)
 #include <unistd.h>
 #endif
 #endif
 
 #if defined(XP_MAC)
 #include <AppleEvents.h>
 #include "pprthred.h"
 #include "primpl.h"
@@ -58,22 +66,27 @@ struct PLEventQueue {
     ((PLEvent*) ((char*) (_qp) - offsetof(PLEvent, link)))
 
 static PRStatus    _pl_SetupNativeNotifier(PLEventQueue* self);
 static void    _pl_CleanupNativeNotifier(PLEventQueue* self);
 static PRStatus    _pl_NativeNotify(PLEventQueue* self);
 static PRStatus    _pl_AcknowledgeNativeNotify(PLEventQueue* self);
 
 
-#if defined(_WIN32) || defined(WIN16)
+#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
 PLEventQueue * _pr_main_event_queue;
+HWND _pr_eventReceiverWindow;
+#if defined(OS2)
+BOOL rc;
+ULONG _pr_PostEventMsgId;
+#else
 UINT _pr_PostEventMsgId;
-HWND _pr_eventReceiverWindow;
 static char *_pr_eventWindowClass = "NSPR:EventWindow";
 #endif
+#endif
 
 /*******************************************************************************
  * Event Queue Operations
  ******************************************************************************/
 
 PR_IMPLEMENT(PLEventQueue*)
 PL_CreateEventQueue(char* name, PRThread* handlerThread)
 {
@@ -532,34 +545,43 @@ static PRStatus
 #   define NOTIFY_TOKEN    0xFA
     PRInt32 count;
     unsigned char buf[] = { NOTIFY_TOKEN };
 
     count = write(self->eventPipe[1], buf, 1);
 	self->notifyCount++;
     return (count == 1) ? PR_SUCCESS : PR_FAILURE;
 
-#elif defined(XP_PC) && ( defined(WINNT) || defined(WIN95) || defined(WIN16))
+#elif defined(XP_PC)
     /*
     ** Post a message to the NSPR window on the main thread requesting 
     ** it to process the pending events. This is only necessary for the
     ** main event queue, since the main thread is waiting for OS events.
     */
+#ifndef XP_OS2
     if (self == _pr_main_event_queue) {
        PostMessage( _pr_eventReceiverWindow, _pr_PostEventMsgId,
                       (WPARAM)0, (LPARAM)self);
     }
     return PR_SUCCESS;
-
-#elif defined(XP_MAC)
+#else
+    if (self == _pr_main_event_queue) {
+       rc = WinPostMsg(_pr_eventReceiverWindow, _pr_PostEventMsgId,
+                       0, MPFROMP(self));
+    }
+    return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE;
+#endif
+#else
+#if defined(XP_MAC)
 
 #pragma unused (self)
     return PR_SUCCESS;    /* XXX can fail? */
 
 #endif
+#endif
 }
 
 static PRStatus
 _pl_AcknowledgeNativeNotify(PLEventQueue* self)
 {
 #if defined(XP_UNIX)
 
     PRInt32 count;
@@ -645,48 +667,83 @@ BOOL WINAPI DllMain (HINSTANCE hDLL, DWO
       break;
   }
 
     return TRUE;
 }
 #endif
 
 
-#if defined(WIN16) || defined(_WIN32)
+#if defined(WIN16) || defined(_WIN32) || defined(XP_OS2)
 PR_IMPLEMENT(PLEventQueue *)
 PL_GetMainEventQueue()
 {
    PR_ASSERT(_pr_main_event_queue);
 
    return _pr_main_event_queue;
 }
-
+#ifdef XP_OS2
+MRESULT EXPENTRY
+_md_EventReceiverProc(HWND hwnd, ULONG uMsg, MPARAM wParam, MPARAM lParam)
+#else
 LRESULT CALLBACK 
 #if defined(WIN16)
 __loadds
 #endif
 _md_EventReceiverProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+#endif
 {
     if (_pr_PostEventMsgId == uMsg )
     {
         PREventQueue *queue = (PREventQueue *)lParam;
 
         PR_ASSERT(queue == PL_GetMainEventQueue());
         if (queue == PL_GetMainEventQueue()) 
         {
             PR_ProcessPendingEvents(queue);
+#ifdef XP_OS2
+            return MRFROMLONG(TRUE);
+#else
             return TRUE;
+#endif
         }
     } 
+#ifdef XP_OS2
+    return WinDefWindowProc(hwnd, uMsg, wParam, lParam);
+#else
     return DefWindowProc(hwnd, uMsg, wParam, lParam);
+#endif
 }
 
 PR_IMPLEMENT(void)
 PL_InitializeEventsLib(char *name)
 {
+#ifdef XP_OS2
+    PSZ _pr_eventWindowClass;
+
+    _pr_main_event_queue = PL_CreateEventQueue(name, PR_GetCurrentThread());
+
+    WinRegisterClass( WinQueryAnchorBlock( HWND_DESKTOP),
+                      _pr_eventWindowClass,
+                      _md_EventReceiverProc,
+                      0, 0);
+
+    _pr_eventReceiverWindow = WinCreateWindow( HWND_DESKTOP,
+                                               _pr_eventWindowClass,
+                                               "", 0,
+                                               0, 0, 0, 0,
+                                               HWND_DESKTOP,
+                                               HWND_TOP,
+                                               0,
+                                               NULL,
+                                               NULL);
+
+    _pr_PostEventMsgId = WinAddAtom(WinQuerySystemAtomTable(),
+                                    "NSPR_PostEvent");
+#else
     WNDCLASS wc;
 
     _pr_main_event_queue = PL_CreateEventQueue(name, PR_GetCurrentThread());
 
     /* Register the windows message for NSPR Event notification */
     _pr_PostEventMsgId = RegisterWindowMessage("NSPR_PostEvent");
 
     /* Register the class for the event receiver window */
@@ -706,26 +763,27 @@ PL_InitializeEventsLib(char *name)
         
     /* Create the event receiver window */
     _pr_eventReceiverWindow = CreateWindow(_pr_eventWindowClass,
                                            "NSPR:EventReceiver",
                                             0, 0, 0, 10, 10,
                                             NULL, NULL, _pr_hInstance,
                                             NULL);
     PR_ASSERT(_pr_eventReceiverWindow);
+#endif
 }
 #endif
 
-#if defined(_WIN32) || defined(WIN16)
+#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
 PR_IMPLEMENT(HWND)
 PR_GetEventReceiverWindow()
 {
-    if(_pr_eventReceiverWindow != NULL)
+    if(_pr_eventReceiverWindow != 0)
     {
 	return _pr_eventReceiverWindow;
     }
 
-    return NULL;
+    return 0;
 
 }
 #endif
 
 /******************************************************************************/
--- a/lib/ds/plevent.h
+++ b/lib/ds/plevent.h
@@ -170,16 +170,18 @@ and to ensure that no more events will b
 #include "prthread.h"
 #include "prmon.h"
 
 /* For HWND */
 #ifdef _WIN32
 #include <windef.h>
 #elif defined(WIN16)
 #include <windows.h>
+#elif defined(XP_OS2)
+#include <os2.h>
 #endif
 
 PR_BEGIN_EXTERN_C
 
 /* Typedefs */
 
 typedef struct PLEvent PLEvent;
 typedef struct PLEventQueue PLEventQueue;
@@ -368,17 +370,17 @@ PR_EXTERN(void)
 PL_DestroyEvent(PLEvent* self);
 
 /*
 ** Removes an event from an event queue.
 */
 PR_EXTERN(void)
 PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
 
-#if defined(_WIN32) || defined(WIN16)
+#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
 PR_EXTERN(HWND)
 PR_GetEventReceiverWindow();
 #endif
 
 
 /*******************************************************************************
  * Private Stuff
  ******************************************************************************/
--- a/lib/ds/plhash.h
+++ b/lib/ds/plhash.h
@@ -27,17 +27,25 @@
 PR_BEGIN_EXTERN_C
 
 typedef struct PLHashEntry  PLHashEntry;
 typedef struct PLHashTable  PLHashTable;
 typedef PRUint32 PLHashNumber;
 #define PL_HASH_BITS 32  /* Number of bits in PLHashNumber */
 typedef PLHashNumber (PR_CALLBACK *PLHashFunction)(const void *key);
 typedef PRIntn (PR_CALLBACK *PLHashComparator)(const void *v1, const void *v2);
-typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn index, void *arg);
+
+#if defined(XP_OS2_VACPP) && defined(VACPP_FLIP) /* for nsSpaceManager.cpp */
+PR_END_EXTERN_C                                  /* and nsHTMLDocument.cpp */
+#endif
+typedef PRIntn (PR_CALLBACK *PLHashEnumerator)(PLHashEntry *he, PRIntn i, void *arg);
+
+#if defined(XP_OS2_VACPP) && defined(VACPP_FLIP)
+PR_BEGIN_EXTERN_C
+#endif
 
 /* Flag bits in PLHashEnumerator's return value */
 #define HT_ENUMERATE_NEXT       0       /* continue enumerating entries */
 #define HT_ENUMERATE_STOP       1       /* stop enumerating entries */
 #define HT_ENUMERATE_REMOVE     2       /* remove and free the current entry */
 #define HT_ENUMERATE_UNHASH     4       /* just unhash the current entry */
 
 typedef struct PLHashAllocOps {
--- a/lib/libc/src/Makefile
+++ b/lib/libc/src/Makefile
@@ -49,17 +49,21 @@ CSRCS =\
 
 LIBRARY_NAME	= plc
 LIBRARY_VERSION	= $(MOD_VERSION)
 
 RELEASE_LIBS = $(TARGETS)
 
 ifeq ($(OS_ARCH),WINNT)
 ifeq (,$(filter-out WIN16 OS2,$(OS_TARGET)))
+ifdef XP_OS2_EMX
+EXTRA_LIBS = -L$(DIST)/lib -lnspr$(MOD_VERSION)
+else
 EXTRA_LIBS = $(DIST)/lib/nspr$(MOD_VERSION).lib
+endif
 else
 DLLBASE=/BASE:0x30000000
 RES=$(OBJDIR)/plc.res
 RESNAME=$(MOD_DEPTH)/pr/src/nspr.rc
 EXTRA_LIBS = $(DIST)/lib/libnspr$(MOD_VERSION).lib
 
 ifdef MOZ_DEBUG
 ifdef GLOWCODE
@@ -96,27 +100,37 @@ endif
 
 include $(MOD_DEPTH)/config/rules.mk
 
 #
 # Version information generation (begin)
 #
 ECHO = echo
 TINC = $(OBJDIR)/_pl_bld.h
-PROD = libplc$(MOD_VERSION).$(DLL_SUFFIX)
+ifeq ($(OS_TARGET),OS2)
+PROD = nspr$(MOD_VERSION).$(DLL_SUFFIX)
+else
+PROD = plc$(MOD_VERSION).$(DLL_SUFFIX)
+endif
 NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
 SH_DATE = $(shell date)
 SH_NOW = $(shell $(NOW))
 
 ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),OS2)
+        SUF =
+else
 	SUF = i64
+endif
 else
 	SUF = LL
 endif
 
+GARBAGE += $(TINC)
+
 $(TINC):
 	@$(MAKE_OBJDIR)
 	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
 	@if test ! -z "$(SH_NOW)"; then \
 	    $(ECHO) '#define _BUILD_TIME $(SH_NOW)$(SUF)' >> $(TINC); \
 	fi
 	@$(ECHO) '#define _PRODUCTION "$(PROD)"' >> $(TINC)
 
@@ -142,9 +156,8 @@ ifdef SHARED_LIBRARY
 	$(INSTALL) -m 444 $(SHARED_LIBRARY) $(DIST)/bin
 endif
 ifeq ($(MOZ_BITS),16)
 	$(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/lib
 	$(INSTALL) -m 444 $(TARGETS) $(MOZ_DIST)/bin
 endif
 
 install:: export
-
--- a/pr/include/md/Makefile
+++ b/pr/include/md/Makefile
@@ -33,17 +33,17 @@ endif
 
 ifeq ($(OS_ARCH),WINNT)
 ifeq ($(OS_TARGET), WIN95)
 MDCPUCFG_H = _win95.cfg
 else
 ifeq ($(OS_TARGET), WIN16)
 MDCPUCFG_H = _win16.cfg
 else
-ifeq ($(OS_TARGET), OS2)
+ifeq ($(OS_TARGET),OS2)
 MDCPUCFG_H = _os2.cfg
 else
 MDCPUCFG_H = _winnt.cfg
 endif
 endif
 endif
 endif
 
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -15,45 +15,54 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 #ifndef nspr_os2_defs_h___
 #define nspr_os2_defs_h___
 
 #define INCL_DOS
+#define INCL_DOSPROCESS
 #define INCL_DOSERRORS
 #define INCL_WIN
 #define INCL_WPS
-#define TID OS2TID   /* global rename in OS2 H's!               */
 #include <os2.h>
-#undef TID           /* and restore                             */
 #include <sys/select.h>
 
 #include "prio.h"
 
 #include <errno.h>
 
+#ifdef XP_OS2_EMX
+/*
+ * EMX-specific tweaks:
+ *    o Use stricmp instead of strcmpi.
+ *    o Use errno rather than sock_errno()
+ *    o Use close rather than soclose
+ *    o Ignore sock_init calls.
+ */
+#define strcmpi stricmp 
+#define sock_errno() errno
+#define soclose close
+#define sock_init()
+#endif
+
 /*
  * Internal configuration macros
  */
 
 #define PR_LINKER_ARCH      "os2"
 #define _PR_SI_SYSNAME        "OS2"
 #define _PR_SI_ARCHITECTURE   "x86"    /* XXXMB hardcode for now */
 
 #define HAVE_DLL
 #undef  HAVE_THREAD_AFFINITY
 #define HAVE_SOCKET_REUSEADDR
 #define HAVE_SOCKET_KEEPALIVE
-
-/*********************************************                                                
-/* We don't have atomic ops on OS/2 natively */
-/* #define _PR_HAVE_ATOMIC_OPS               */
-/*********************************************/
+#undef  _PR_HAVE_ATOMIC_OPS
 
 #define HANDLE unsigned long
 #define HINSTANCE HMODULE
 
 /* --- Common User-Thread/Native-Thread Definitions --------------------- */
 
 /* --- Globals --- */
 extern struct PRLock                      *_pr_schedLock;
@@ -68,35 +77,33 @@ typedef PRInt32	                PR_CONTE
 typedef int (*FARPROC)();
 
 #define _MD_MAGIC_THREAD	0x22222222
 #define _MD_MAGIC_THREADSTACK	0x33333333
 #define _MD_MAGIC_SEGMENT	0x44444444
 #define _MD_MAGIC_DIR		0x55555555
 #define _MD_MAGIC_CV        0x66666666
 
-#define CALLBACK
-
 typedef struct _MDSemaphore
 {
    HEV sem;
 } MDSEM;
 
 struct _MDCPU {
     int              unused;
 }; 
 
 struct _MDThread {
     MDSEM            blocked_sema;       /* Threads block on this when waiting
                                          * for IO or CondVar.
                                          */
     PRBool           inCVWaitQueue;     /* PR_TRUE if the thread is in the
                                          * wait queue of some cond var.
                                          * PR_FALSE otherwise.  */
-    OS2TID           handle;            /* OS/2 thread handle */
+    TID              handle;            /* OS/2 thread handle */
     void            *sp;                /* only valid when suspended */
     PRUint32         magic;             /* for debugging */
     PR_CONTEXT_TYPE  gcContext;         /* Thread context for GC */
     struct PRThread *prev, *next;       /* used by the cvar wait queue to
                                          * chain the PRThread structures
                                          * together */
 };
 
@@ -171,42 +178,45 @@ struct _MDProcess {
    PID pid;
 };
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
 /* --- IO stuff --- */
 
-#define _MD_OPEN                      _PR_MD_OPEN
-#define _MD_READ                      _PR_MD_READ
-#define _MD_WRITE                     _PR_MD_WRITE
-#define _MD_WRITEV                    _PR_MD_WRITEV
-#define _MD_LSEEK                     _PR_MD_LSEEK
-#define _MD_LSEEK64                   _PR_MD_LSEEK64
+#define _MD_OPEN                      (_PR_MD_OPEN)
+#define _MD_READ                      (_PR_MD_READ)
+#define _MD_WRITE                     (_PR_MD_WRITE)
+#define _MD_WRITEV                    (_PR_MD_WRITEV)
+#define _MD_LSEEK                     (_PR_MD_LSEEK)
+#define _MD_LSEEK64                   (_PR_MD_LSEEK64)
 extern PRInt32 _MD_CloseFile(PRInt32 osfd);
 #define _MD_CLOSE_FILE                _MD_CloseFile
-#define _MD_GETFILEINFO               _PR_MD_GETFILEINFO
-#define _MD_GETOPENFILEINFO           _PR_MD_GETOPENFILEINFO
-#define _MD_GETOPENFILEINFO64(a, b)   _PR_MD_GETOPENFILEINFO64(a, b)
-#define _MD_STAT                      _PR_MD_STAT
-#define _MD_RENAME                    _PR_MD_RENAME     
-#define _MD_ACCESS                    _PR_MD_ACCESS     
-#define _MD_DELETE                    _PR_MD_DELETE     
-#define _MD_MKDIR                     _PR_MD_MKDIR      
-#define _MD_RMDIR                     _PR_MD_RMDIR      
-#define _MD_LOCKFILE                  _PR_MD_LOCKFILE
-#define _MD_TLOCKFILE                 _PR_MD_TLOCKFILE
-#define _MD_UNLOCKFILE                _PR_MD_UNLOCKFILE
+#define _MD_GETFILEINFO               (_PR_MD_GETFILEINFO)
+#define _MD_GETFILEINFO64             (_PR_MD_GETFILEINFO64)
+#define _MD_GETOPENFILEINFO           (_PR_MD_GETOPENFILEINFO)
+#define _MD_GETOPENFILEINFO64         (_PR_MD_GETOPENFILEINFO64)
+#define _MD_STAT                      (_PR_MD_STAT)
+#define _MD_RENAME                    (_PR_MD_RENAME)
+#define _MD_ACCESS                    (_PR_MD_ACCESS)
+#define _MD_DELETE                    (_PR_MD_DELETE)
+#define _MD_MKDIR                     (_PR_MD_MKDIR)
+#define _MD_RMDIR                     (_PR_MD_RMDIR)
+#define _MD_LOCKFILE                  (_PR_MD_LOCKFILE)
+#define _MD_TLOCKFILE                 (_PR_MD_TLOCKFILE)
+#define _MD_UNLOCKFILE                (_PR_MD_UNLOCKFILE)
 
 /* --- Socket IO stuff --- */
 
 /* The ones that don't map directly may need to be re-visited... */
+#ifdef XP_OS2_VACPP
 #define EPIPE                     EBADF
 #define EIO                       ECONNREFUSED
+#endif
 #define _MD_EACCES                EACCES
 #define _MD_EADDRINUSE            EADDRINUSE
 #define _MD_EADDRNOTAVAIL         EADDRNOTAVAIL
 #define _MD_EAFNOSUPPORT          EAFNOSUPPORT
 #define _MD_EAGAIN                EWOULDBLOCK
 #define _MD_EALREADY              EALREADY
 #define _MD_EBADF                 EBADF
 #define _MD_ECONNREFUSED          ECONNREFUSED
@@ -224,132 +234,132 @@ extern PRInt32 _MD_CloseFile(PRInt32 osf
 #define _MD_EWOULDBLOCK           EWOULDBLOCK
 #define _MD_GET_SOCKET_ERROR()    sock_errno()
 #ifndef INADDR_LOOPBACK /* For some reason this is not defined in OS2 tcpip */
 /*  #define INADDR_LOOPBACK         INADDR_ANY */
 #endif  
 
 extern void _MD_MakeNonblock(PRFileDesc *f);
 #define _MD_MAKE_NONBLOCK             _MD_MakeNonblock
-#define _MD_SHUTDOWN                  _PR_MD_SHUTDOWN
+#define _MD_SHUTDOWN                  (_PR_MD_SHUTDOWN)
 #define _MD_LISTEN(s, backlog)        listen(s->secret->md.osfd,backlog)
 extern PRInt32 _MD_CloseSocket(PRInt32 osfd);
 #define _MD_CLOSE_SOCKET              _MD_CloseSocket
-#define _MD_SENDTO                    _PR_MD_SENDTO
-#define _MD_RECVFROM                  _PR_MD_RECVFROM
+#define _MD_SENDTO                    (_PR_MD_SENDTO)
+#define _MD_RECVFROM                  (_PR_MD_RECVFROM)
 #define _MD_SOCKETPAIR(s, type, proto, sv) -1
-#define _MD_GETSOCKNAME               _PR_MD_GETSOCKNAME
-#define _MD_GETPEERNAME               _PR_MD_GETPEERNAME
-#define _MD_GETSOCKOPT                _PR_MD_GETSOCKOPT
-#define _MD_SETSOCKOPT                _PR_MD_SETSOCKOPT
+#define _MD_GETSOCKNAME               (_PR_MD_GETSOCKNAME)
+#define _MD_GETPEERNAME               (_PR_MD_GETPEERNAME)
+#define _MD_GETSOCKOPT                (_PR_MD_GETSOCKOPT)
+#define _MD_SETSOCKOPT                (_PR_MD_SETSOCKOPT)
 #define _MD_SELECT                    select
 #define _MD_FSYNC                     _PR_MD_FSYNC
 
 #define _MD_INIT_ATOMIC               _PR_MD_INIT_ATOMIC
 #define _MD_ATOMIC_INCREMENT(x)       _PR_MD_ATOMIC_INCREMENT(x)
 #define _MD_ATOMIC_ADD(x,y)			  _PR_MD_ATOMIC_ADD(x,y)
 #define _MD_ATOMIC_DECREMENT(x)       _PR_MD_ATOMIC_DECREMENT(x)
 #define _MD_ATOMIC_SET(x,y)           _PR_MD_ATOMIC_SET(x, y)
 
-#define _MD_INIT_IO                   _PR_MD_INIT_IO
-#define _MD_TRANSMITFILE              _PR_MD_TRANSMITFILE
-
+#define _MD_INIT_IO                   (_PR_MD_INIT_IO)
+#define _MD_TRANSMITFILE              (_PR_MD_TRANSMITFILE)
+#define _MD_PR_POLL                   (_PR_MD_PR_POLL)
 
 /* win95 doesn't have async IO */
-#define _MD_SOCKET                    _PR_MD_SOCKET
+#define _MD_SOCKET                    (_PR_MD_SOCKET)
 extern PRInt32 _MD_SocketAvailable(PRFileDesc *fd);
 #define _MD_SOCKETAVAILABLE           _MD_SocketAvailable
-#define _MD_CONNECT                   _PR_MD_CONNECT
+#define _MD_CONNECT                   (_PR_MD_CONNECT)
 extern PRInt32 _MD_Accept(PRFileDesc *fd, PRNetAddr *raddr, PRUint32 *rlen,
         PRIntervalTime timeout);
 #define _MD_ACCEPT                    _MD_Accept
-#define _MD_BIND                      _PR_MD_BIND
-#define _MD_RECV                      _PR_MD_RECV
-#define _MD_SEND                      _PR_MD_SEND
+#define _MD_BIND                      (_PR_MD_BIND)
+#define _MD_RECV                      (_PR_MD_RECV)
+#define _MD_SEND                      (_PR_MD_SEND)
 
 /* --- Scheduler stuff --- */
 /* #define _MD_PAUSE_CPU                 _PR_MD_PAUSE_CPU */
 #define _MD_PAUSE_CPU
 
 /* --- DIR stuff --- */
 #define PR_DIRECTORY_SEPARATOR        '\\'
 #define PR_DIRECTORY_SEPARATOR_STR    "\\"
 #define PR_PATH_SEPARATOR		';'
 #define PR_PATH_SEPARATOR_STR		";"
 #define _MD_ERRNO()                   errno
-#define _MD_OPEN_DIR                  _PR_MD_OPEN_DIR
-#define _MD_CLOSE_DIR                 _PR_MD_CLOSE_DIR
-#define _MD_READ_DIR                  _PR_MD_READ_DIR
+#define _MD_OPEN_DIR                  (_PR_MD_OPEN_DIR)
+#define _MD_CLOSE_DIR                 (_PR_MD_CLOSE_DIR)
+#define _MD_READ_DIR                  (_PR_MD_READ_DIR)
 
 /* --- Segment stuff --- */
 #define _MD_INIT_SEGS()
 #define _MD_ALLOC_SEGMENT(seg, size, vaddr)   0
 #define _MD_FREE_SEGMENT(seg)
 
 /* --- Environment Stuff --- */
-#define _MD_GET_ENV                 _PR_MD_GET_ENV
-#define _MD_PUT_ENV                 _PR_MD_PUT_ENV
+#define _MD_GET_ENV                 (_PR_MD_GET_ENV)
+#define _MD_PUT_ENV                 (_PR_MD_PUT_ENV)
 
 /* --- Threading Stuff --- */
 #define _MD_DEFAULT_STACK_SIZE      32767L
-#define _MD_INIT_THREAD             _PR_MD_INIT_THREAD
-#define _MD_INIT_ATTACHED_THREAD    _PR_MD_INIT_THREAD
-#define _MD_INIT_PRIMORDIAL_THREAD  _PR_MD_INIT_PRIMORDIAL_THREAD
-#define _MD_CREATE_THREAD           _PR_MD_CREATE_THREAD
-#define _MD_YIELD                   _PR_MD_YIELD
-#define _MD_SET_PRIORITY            _PR_MD_SET_PRIORITY
-#define _MD_CLEAN_THREAD            _PR_MD_CLEAN_THREAD
-#define _MD_SETTHREADAFFINITYMASK   _PR_MD_SETTHREADAFFINITYMASK
-#define _MD_GETTHREADAFFINITYMASK   _PR_MD_GETTHREADAFFINITYMASK
-#define _MD_EXIT_THREAD             _PR_MD_EXIT_THREAD
-#define _MD_SUSPEND_THREAD          _PR_MD_SUSPEND_THREAD
-#define _MD_RESUME_THREAD           _PR_MD_RESUME_THREAD
-#define _MD_SUSPEND_CPU             _PR_MD_SUSPEND_CPU
-#define _MD_RESUME_CPU              _PR_MD_RESUME_CPU
-#define _MD_WAKEUP_CPUS             _PR_MD_WAKEUP_CPUS
+#define _MD_INIT_THREAD             (_PR_MD_INIT_THREAD)
+#define _MD_INIT_ATTACHED_THREAD    (_PR_MD_INIT_THREAD)
+#define _MD_INIT_PRIMORDIAL_THREAD  (_PR_MD_INIT_PRIMORDIAL_THREAD)
+#define _MD_CREATE_THREAD           (_PR_MD_CREATE_THREAD)
+#define _MD_YIELD                   (_PR_MD_YIELD)
+#define _MD_SET_PRIORITY            (_PR_MD_SET_PRIORITY)
+#define _MD_CLEAN_THREAD            (_PR_MD_CLEAN_THREAD)
+#define _MD_SETTHREADAFFINITYMASK   (_PR_MD_SETTHREADAFFINITYMASK)
+#define _MD_GETTHREADAFFINITYMASK   (_PR_MD_GETTHREADAFFINITYMASK)
+#define _MD_EXIT_THREAD             (_PR_MD_EXIT_THREAD)
+#define _MD_SUSPEND_THREAD          (_PR_MD_SUSPEND_THREAD)
+#define _MD_RESUME_THREAD           (_PR_MD_RESUME_THREAD)
+#define _MD_SUSPEND_CPU             (_PR_MD_SUSPEND_CPU)
+#define _MD_RESUME_CPU              (_PR_MD_RESUME_CPU)
+#define _MD_WAKEUP_CPUS             (_PR_MD_WAKEUP_CPUS)
 #define _MD_BEGIN_SUSPEND_ALL()
 #define _MD_BEGIN_RESUME_ALL()
 #define _MD_END_SUSPEND_ALL()
 #define _MD_END_RESUME_ALL()
 
 /* --- Lock stuff --- */
 #define _PR_LOCK                      _MD_LOCK
 #define _PR_UNLOCK					  _MD_UNLOCK
 
 #define _MD_NEW_LOCK(lock)            (DosCreateMutexSem(0, &((lock)->mutex), 0, 0),(lock)->notified.length=0,(lock)->notified.link=NULL,PR_SUCCESS)
 #define _MD_FREE_LOCK(lock)           DosCloseMutexSem(((lock)->mutex))
 #define _MD_LOCK(lock)                DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT)
 #define _MD_TEST_AND_LOCK(lock)       (DosRequestMutexSem(((lock)->mutex), SEM_INDEFINITE_WAIT),PR_SUCCESS)
-#define _MD_UNLOCK                    _PR_MD_UNLOCK
+#define _MD_UNLOCK                    (_PR_MD_UNLOCK)
 
 /* --- lock and cv waiting --- */
-#define _MD_WAIT                      _PR_MD_WAIT
-#define _MD_WAKEUP_WAITER             _PR_MD_WAKEUP_WAITER
+#define _MD_WAIT                      (_PR_MD_WAIT)
+#define _MD_WAKEUP_WAITER             (_PR_MD_WAKEUP_WAITER)
 
 /* --- CVar ------------------- */
-#define _MD_WAIT_CV					  _PR_MD_WAIT_CV
-#define _MD_NEW_CV					  _PR_MD_NEW_CV
-#define _MD_FREE_CV					  _PR_MD_FREE_CV
-#define _MD_NOTIFY_CV				  _PR_MD_NOTIFY_CV	
-#define _MD_NOTIFYALL_CV			  _PR_MD_NOTIFYALL_CV
+#define _MD_WAIT_CV					  (_PR_MD_WAIT_CV)
+#define _MD_NEW_CV					  (_PR_MD_NEW_CV)
+#define _MD_FREE_CV					  (_PR_MD_FREE_CV)
+#define _MD_NOTIFY_CV				  (_PR_MD_NOTIFY_CV	)
+#define _MD_NOTIFYALL_CV			  (_PR_MD_NOTIFYALL_CV)
 
    /* XXXMB- the IOQ stuff is certainly not working correctly yet. */
 /* extern  struct _MDLock              _pr_ioq_lock; */
 #define _MD_IOQ_LOCK()                
 #define _MD_IOQ_UNLOCK()              
 
 
 /* --- Initialization stuff --- */
 #define _MD_START_INTERRUPTS()
 #define _MD_STOP_INTERRUPTS()
 #define _MD_DISABLE_CLOCK_INTERRUPTS()
 #define _MD_ENABLE_CLOCK_INTERRUPTS()
 #define _MD_BLOCK_CLOCK_INTERRUPTS()
 #define _MD_UNBLOCK_CLOCK_INTERRUPTS()
-#define _MD_EARLY_INIT                _PR_MD_EARLY_INIT
+#define _MD_EARLY_INIT                (_PR_MD_EARLY_INIT)
 #define _MD_FINAL_INIT()
 #define _MD_INIT_CPUS()
 #define _MD_INIT_RUNNING_CPU(cpu)
 
 struct PRProcess;
 struct PRProcessAttr;
 
 #define _MD_CREATE_PROCESS _PR_CreateOS2Process
@@ -367,48 +377,54 @@ extern PRStatus _PR_DetachOS2Process(str
 #define _MD_WAIT_PROCESS _PR_WaitOS2Process
 extern PRStatus _PR_WaitOS2Process(struct PRProcess *process, 
     PRInt32 *exitCode);
 
 #define _MD_KILL_PROCESS _PR_KillOS2Process
 extern PRStatus _PR_KillOS2Process(struct PRProcess *process);
 
 #define _MD_CLEANUP_BEFORE_EXIT()
+#define _MD_EXIT                          (_PR_MD_EXIT)
 #define _MD_INIT_CONTEXT
 #define _MD_SWITCH_CONTEXT
 #define _MD_RESTORE_CONTEXT
 
 /* --- Intervals --- */
-#define _MD_INTERVAL_INIT                 _PR_MD_INTERVAL_INIT
-#define _MD_GET_INTERVAL                  _PR_MD_GET_INTERVAL
-#define _MD_INTERVAL_PER_SEC              _PR_MD_INTERVAL_PER_SEC
+#define _MD_INTERVAL_INIT                 (_PR_MD_INTERVAL_INIT)
+#define _MD_GET_INTERVAL                  (_PR_MD_GET_INTERVAL)
+#define _MD_INTERVAL_PER_SEC              (_PR_MD_INTERVAL_PER_SEC)
 #define _MD_INTERVAL_PER_MILLISEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000)
 #define _MD_INTERVAL_PER_MICROSEC()       (_PR_MD_INTERVAL_PER_SEC() / 1000000)
 
 /* --- Native-Thread Specific Definitions ------------------------------- */
 
 typedef struct __NSPR_TLS
 {
     struct PRThread  *_pr_thread_last_run;
     struct PRThread  *_pr_currentThread;
     struct _PRCPU    *_pr_currentCPU;
 } _NSPR_TLS;
 
 extern _NSPR_TLS*  pThreadLocalStorage;
-PR_IMPLEMENT(void) _PR_MD_ENSURE_TLS();
+PR_EXTERN(void) _PR_MD_ENSURE_TLS(void);
 
 #define _MD_CURRENT_THREAD() pThreadLocalStorage->_pr_currentThread
 #define _MD_SET_CURRENT_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentThread = (_thread)
 
 #define _MD_LAST_THREAD() pThreadLocalStorage->_pr_thread_last_run
 #define _MD_SET_LAST_THREAD(_thread) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_thread_last_run = (_thread)
 
 #define _MD_CURRENT_CPU() pThreadLocalStorage->_pr_currentCPU
 #define _MD_SET_CURRENT_CPU(_cpu) _PR_MD_ENSURE_TLS(); pThreadLocalStorage->_pr_currentCPU = (_cpu)
 
+/* lth. #define _MD_SET_INTSOFF(_val) (_pr_ints_off = (_val)) */
+/* lth. #define _MD_GET_INTSOFF() _pr_ints_off */
+/* lth. #define _MD_INCREMENT_INTSOFF() (_pr_ints_off++) */
+/* lth. #define _MD_DECREMENT_INTSOFF() (_pr_ints_off--) */
+
 /* --- Scheduler stuff --- */
 #define LOCK_SCHEDULER()                 0
 #define UNLOCK_SCHEDULER()               0
 #define _PR_LockSched()                	 0
 #define _PR_UnlockSched()                0
 
 /* --- Initialization stuff --- */
 #define _MD_INIT_LOCKS()
@@ -432,20 +448,17 @@ extern void * _MD_MemMap(struct PRFileMa
 
 extern PRStatus _MD_MemUnmap(void *addr, PRUint32 size);
 #define _MD_MEM_UNMAP _MD_MemUnmap
 
 extern PRStatus _MD_CloseFileMap(struct PRFileMap *fmap);
 #define _MD_CLOSE_FILE_MAP _MD_CloseFileMap
 
 /* Some stuff for setting up thread contexts */
-#undef DWORD
-#undef PDWORD
-typedef unsigned long DWORD;
-typedef unsigned long *PDWORD;
+typedef ULONG DWORD, *PDWORD;
 
 /* The following definitions and two structures are new in OS/2 Warp 4.0.
  */
 #ifndef CONTEXT_CONTROL
 #define CONTEXT_CONTROL        0x00000001
 #define CONTEXT_INTEGER        0x00000002
 #define CONTEXT_SEGMENTS       0x00000004
 #define CONTEXT_FLOATING_POINT 0x00000008
@@ -476,23 +489,23 @@ typedef struct _CONTEXTRECORD {
     ULONG     ctx_SegCs;     /*  CS register. */
     ULONG     ctx_EFlags;    /*  EFLAGS register. */
     ULONG     ctx_RegEsp;    /*  ESP register. */
     ULONG     ctx_SegSs;     /*  SS register. */
 } CONTEXTRECORD, *PCONTEXTRECORD;
 #pragma pack()
 #endif
 
-extern APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
+extern APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
 
 /*
 #define _pr_tid            (((PTIB2)_getTIBvalue(offsetof(TIB, tib_ptib2)))->tib2_ultid)
 #define _pr_current_Thread (_system_tls[_pr_tid-1].__pr_current_thread)
 */
 
 /* Some simple mappings of Windows API's to OS/2 API's to make our lives a
  * little bit easier.  Only add one here if it is a DIRECT mapping.  We are
  * not emulating anything.  Just mapping.
  */
 #define FreeLibrary(x) DosFreeModule(x)
-#define OutputDebugString(str) ;
+#define OutputDebugString(x)
                                
 #endif /* nspr_os2_defs_h___ */
--- a/pr/include/md/_os2_errors.h
+++ b/pr/include/md/_os2_errors.h
@@ -18,17 +18,16 @@
 
 #ifndef nspr_os2_errors_h___
 #define nspr_os2_errors_h___
 
 #include "md/_os2.h"
 #ifndef assert
   #include <assert.h>
 #endif  
-#include <nerrno.h>
 
 PR_EXTERN(void) _MD_os2_map_opendir_error(PRInt32 err);
 #define	_PR_MD_MAP_OPENDIR_ERROR	_MD_os2_map_opendir_error
 
 PR_EXTERN(void) _MD_os2_map_closedir_error(PRInt32 err);
 #define	_PR_MD_MAP_CLOSEDIR_ERROR	_MD_os2_map_closedir_error
 
 PR_EXTERN(void) _MD_unix_readdir_error(PRInt32 err);
--- a/pr/include/md/_pcos.h
+++ b/pr/include/md/_pcos.h
@@ -37,34 +37,37 @@
 #else
 #define GCPTR
 #endif
 
 /*
 ** Routines for processing command line arguments
 */
 PR_BEGIN_EXTERN_C
-
+#ifndef XP_OS2_EMX
 extern char *optarg;
 extern int optind;
 extern int getopt(int argc, char **argv, char *spec);
-
+#endif
 PR_END_EXTERN_C
 
 #define gcmemcpy(a,b,c) memcpy(a,b,c)
 
 
 /*
 ** Definitions of directory structures amd functions
 ** These definitions are from:
 **      <dirent.h>
 */
 #ifdef MOZ_BITS
 #include <time.h>
 #endif
+#ifdef XP_OS2_EMX
+#include <sys/types.h>
+#endif
 #include <sys/stat.h>
 #include <io.h>
 #include <fcntl.h>          /* O_BINARY */
 
 typedef int PROSFD;
 
 /*
 ** Undo the macro define in the Microsoft header files...
--- a/pr/include/prtypes.h
+++ b/pr/include/prtypes.h
@@ -102,17 +102,21 @@
 
 #elif defined(XP_OS2) 
 #define PR_EXTERN(__type) extern __type
 #define PR_IMPLEMENT(__type) __type
 #define PR_EXTERN_DATA(__type) extern __type
 #define PR_IMPLEMENT_DATA(__type) __type
 #define PR_CALLBACK
 #define PR_CALLBACK_DECL
-#define PR_STATIC_CALLBACK(__x) __x _Optlink
+#ifndef XP_OS2_VACPP
+#define PR_STATIC_CALLBACK(__x) static __x
+#else
+#define PR_STATIC_CALLBACK(__x) static __x _Optlink
+#endif
 
 #else /* Unix */
 #define PR_EXTERN(__type) extern __type
 #define PR_IMPLEMENT(__type) __type
 #define PR_EXTERN_DATA(__type) extern __type
 #define PR_IMPLEMENT_DATA(__type) __type
 #define PR_CALLBACK
 #define PR_CALLBACK_DECL
--- a/pr/src/Makefile
+++ b/pr/src/Makefile
@@ -126,17 +126,17 @@ OS_LIBS		= -lsocket -lc
 endif
 
 ifeq ($(OS_ARCH),NEWS-OS)
 OS_LIBS		= -lsocket -lnsl -lgen -lresolv
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 ifeq ($(OS_TARGET),OS2)
-OS_LIBS		= so32dll.lib tcp32dll.lib
+# We define this in os2.mk.
 else
 ifneq ($(OS_TARGET),WIN16)
 OS_LIBS		= wsock32.lib winmm.lib
 endif
 endif
 endif
 
 #
@@ -252,17 +252,17 @@ OBJS +=	md/windows/$(OBJDIR)/w95io.$(OBJ
 	md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w95dllmain.$(OBJ_SUFFIX)
 else
-ifeq ($(OS_TARGET), OS2)
+ifeq ($(OS_TARGET),OS2)
 OBJS +=	md/os2/$(OBJDIR)/os2io.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2sock.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2thred.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2cv.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2gc.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2misc.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2inrval.$(OBJ_SUFFIX) \
 	md/os2/$(OBJDIR)/os2sem.$(OBJ_SUFFIX)	\
@@ -287,19 +287,17 @@ else
 	THREAD_DIR=threads/combined/$(OBJDIR)
 
 ifeq ($(OS_ARCH), MAC)
 	MD_DIR = md/mac/$(OBJDIR)
 else
 	MD_DIR = md/unix/$(OBJDIR)
 	include md/unix/objs.mk
 endif
-
 endif
-
 LIBRARY_NAME = nspr
 LIBRARY_VERSION = $(MOD_VERSION)
 
 RELEASE_LIBS = $(TARGETS)
 
 include $(MOD_DEPTH)/config/rules.mk
 
 ifeq ($(BUILD_AIX_RTL_LIBC),1)
@@ -308,23 +306,31 @@ TARGETS		+= $(AIX_RTL_LIBC)
 endif
 
 #
 # Version information generation (begin)
 #
 ECHO = echo
 INCLUDES = -I$(DIST)/include
 TINC = $(OBJDIR)/_pr_bld.h
+ifeq ($(OS_TARGET),OS2)
+PROD = nspr$(MOD_VERSION).$(DLL_SUFFIX)
+else
 PROD = libnspr$(MOD_VERSION).$(DLL_SUFFIX)
+endif
 NOW = $(MOD_DEPTH)/config/$(OBJDIR)/now
 SH_DATE = $(shell date)
 SH_NOW = $(shell $(NOW))
 
 ifeq ($(OS_ARCH), WINNT)
+ifeq ($(OS_TARGET),OS2)
+        SUF =
+else
 	SUF = i64
+endif
 else
 	SUF = LL
 endif
 
 $(TINC):
 	@$(MAKE_OBJDIR)
 	@$(ECHO) '#define _BUILD_STRING "$(SH_DATE)"' > $(TINC)
 	@if test ! -z "$(SH_NOW)"; then \
--- a/pr/src/io/prlog.c
+++ b/pr/src/io/prlog.c
@@ -47,17 +47,17 @@ static PRLock *_pr_logLock;
     _PR_LOCK_UNLOCK(_pr_logLock); \
     PR_ASSERT(_me == _PR_MD_CURRENT_THREAD()); \
     if (!_PR_IS_NATIVE_THREAD(_me)) \
         _PR_INTSON(_is); \
 }
 
 #endif
 
-#ifdef XP_PC
+#if defined(XP_PC) && !defined(XP_OS2_VACPP)
 #define strcasecmp stricmp
 #define strncasecmp strnicmp
 #endif
 
 /*
  * On NT, we can't define _PUT_LOG as PR_Write or _PR_MD_WRITE,
  * because every asynchronous file io operation leads to a fiber context
  * switch.  So we define _PUT_LOG as fputs (from stdio.h).  A side
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -401,17 +401,21 @@ static PRStatus PR_CALLBACK SocketBind(P
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 			return PR_FAILURE;
 		}
 	} else {
 #endif
 
 #ifdef HAVE_SOCKET_REUSEADDR
 	if ( setsockopt (fd->secret->md.osfd, (int)SOL_SOCKET, SO_REUSEADDR, 
+#ifdef XP_OS2_VACPP
+	    (char *)&one, sizeof(one) ) < 0) {
+#else
 	    (const void *)&one, sizeof(one) ) < 0) {
+#endif
 		return PR_FAILURE;
 	}
 #endif
 
 #ifdef XP_UNIX
 	}
 #endif
 
@@ -1062,17 +1066,21 @@ PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRIn
 	osfd = _PR_MD_SOCKET(domain, type, proto);
 	if (osfd == -1) {
 		return 0;
 	}
 #ifdef HAVE_SOCKET_KEEPALIVE
 	/* "Keep-alive" packets are specific to TCP. */
 	if (domain == AF_INET && type == SOCK_STREAM) {
 		if (setsockopt(osfd, (int)SOL_SOCKET, SO_KEEPALIVE,
+#ifdef XP_OS2_VACPP
+            (char *)&one, sizeof(one) ) < 0) {
+#else
 		    (const void *) &one, sizeof(one) ) < 0) {
+#endif
 			_PR_MD_CLOSE_SOCKET(osfd);
 			return 0;
 		}
 	}
 #endif
 	if (type == SOCK_STREAM)
 		fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
 	else
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -442,21 +442,19 @@ PR_LoadLibrary(const char *name)
     if (result != NULL) goto unlock;
 
     lm = PR_NEWZAP(PRLibrary);
     if (lm == NULL) goto unlock;
     lm->staticTable = NULL;
 
 #ifdef XP_OS2  /* Why isn't all this stuff in MD code?! */
     {
-        NODL_PROC *pfn;
         HMODULE h;
         UCHAR pszError[_MAX_PATH];
         ULONG ulRc = NO_ERROR;
-        int first_try = 1;
 
         retry:
               ulRc = DosLoadModule(pszError, _MAX_PATH, (PSZ) name, &h);
           if (ulRc != NO_ERROR) {
               PR_DELETE(lm);
               goto unlock;
           }
           lm->name = strdup(name);
@@ -795,17 +793,17 @@ pr_FindSymbolInLib(PRLibrary *lm, const 
         */
 #if !defined(WIN16)
         PR_SetError(PR_FIND_SYMBOL_ERROR, 0);
         return (void*)NULL;
 #endif
     }
     
 #ifdef XP_OS2
-    DosQueryProcAddr(lm->dlh, 0, name, (PFN *) &f);
+    DosQueryProcAddr(lm->dlh, 0, (PSZ) name, (PFN *) &f);
 #endif  /* XP_OS2 */
 
 #if defined(WIN32) || defined(WIN16)
     f = GetProcAddress(lm->dlh, name);
 #endif  /* WIN32 || WIN16 */
 
 #ifdef XP_MAC
     {
--- a/pr/src/md/os2/os2_errors.c
+++ b/pr/src/md/os2/os2_errors.c
@@ -357,19 +357,21 @@ void _MD_os2_map_read_error(PRInt32 err)
 			PR_SetError(PR_CONNECT_RESET_ERROR, err);
 			break;
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break; 
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
 
 void _MD_os2_map_transmitfile_error(PRInt32 err)
 {
@@ -406,19 +408,21 @@ void _MD_os2_map_transmitfile_error(PRIn
 			PR_SetError(PR_FILE_NOT_FOUND_ERROR, err);
 			break;
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
 
 void _MD_os2_map_write_error(PRInt32 err)
 {
@@ -466,19 +470,21 @@ void _MD_os2_map_write_error(PRInt32 err
 			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
 			break;
 		case ECONNREFUSED:
 			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
 			break;
 		case EISCONN:
 			PR_SetError(PR_IS_CONNECTED_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
 
 void _MD_os2_map_lseek_error(PRInt32 err)
 {
@@ -563,19 +569,21 @@ void _MD_os2_map_recv_error(PRInt32 err)
 			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
 			break;
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ERROR_NETNAME_DELETED:
 			PR_SetError(PR_CONNECT_RESET_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -587,19 +595,21 @@ void _MD_os2_map_recvfrom_error(PRInt32 
 			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
 			break;
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ERROR_NETNAME_DELETED:
 			PR_SetError(PR_CONNECT_RESET_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -624,19 +634,21 @@ void _MD_os2_map_send_error(PRInt32 err)
 			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
 			break;
 		case ECONNREFUSED:
 			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
 			break;
 		case EISCONN:
 			PR_SetError(PR_IS_CONNECTED_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ERROR_NETNAME_DELETED:
 			PR_SetError(PR_CONNECT_RESET_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -661,19 +673,21 @@ void _MD_os2_map_sendto_error(PRInt32 er
 			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
 			break;
 		case ECONNREFUSED:
 			PR_SetError(PR_CONNECT_REFUSED_ERROR, err);
 			break;
 		case EISCONN:
 			PR_SetError(PR_IS_CONNECTED_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ERROR_NETNAME_DELETED:
 			PR_SetError(PR_CONNECT_RESET_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -688,19 +702,21 @@ void _MD_os2_map_accept_error(PRInt32 er
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
 		case EOPNOTSUPP:
 			PR_SetError(PR_NOT_TCP_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case EMFILE:
 			PR_SetError(PR_PROC_DESC_TABLE_FULL_ERROR, err);
 			break;
 		case ENOBUFS:
 			PR_SetError(PR_OUT_OF_MEMORY_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
@@ -728,17 +744,19 @@ void _MD_os2_map_acceptex_error(PRInt32 
 }
 
 void _MD_os2_map_connect_error(PRInt32 err)
 {
 	switch (err) {
        case EWOULDBLOCK:
 			PR_SetError(PR_WOULD_BLOCK_ERROR, err);
 			break;
-      case EINPROGRESS:
+        case EINPROGRESS:
+			PR_SetError(PR_IN_PROGRESS_ERROR, err);
+			break;
 		case EALREADY:
 		case EINVAL:
 			PR_SetError(PR_ALREADY_INITIATED_ERROR, err);
 			break;
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case EADDRNOTAVAIL:
@@ -760,37 +778,41 @@ void _MD_os2_map_connect_error(PRInt32 e
 			PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, err);
 			break;
 		case EADDRINUSE:
 			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
 			break;
       case EISCONN:
          PR_SetError(PR_IS_CONNECTED_ERROR, err);
          break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
 
 void _MD_os2_map_bind_error(PRInt32 err)
 {
 	switch (err) {
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case EADDRNOTAVAIL:
 			PR_SetError(PR_ADDRESS_NOT_AVAILABLE_ERROR, err);
 			break;
 		case EADDRINUSE:
 			PR_SetError(PR_ADDRESS_IN_USE_ERROR, err);
 			break;
 		case EACCES:
 			PR_SetError(PR_NO_ACCESS_RIGHTS_ERROR, err);
@@ -844,19 +866,21 @@ void _MD_os2_map_getsockname_error(PRInt
 {
 	switch (err) {
 		case EBADF:
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ENOBUFS:
 			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -869,19 +893,21 @@ void _MD_os2_map_getpeername_error(PRInt
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
 		case ENOTCONN:
 			PR_SetError(PR_NOT_CONNECTED_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ENOBUFS:
 			PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -893,19 +919,21 @@ void _MD_os2_map_getsockopt_error(PRInt3
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
 		case ENOPROTOOPT:
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case EINVAL:
 			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -917,19 +945,21 @@ void _MD_os2_map_setsockopt_error(PRInt3
 			PR_SetError(PR_BAD_DESCRIPTOR_ERROR, err);
 			break;
 		case ENOTSOCK:
 			PR_SetError(PR_NOT_SOCKET_ERROR, err);
 			break;
 		case ENOPROTOOPT:
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, err);
 			break;
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case EINVAL:
 			PR_SetError(PR_BUFFER_OVERFLOW_ERROR, err);
 			break;
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
@@ -985,19 +1015,21 @@ void _MD_os2_map_open_error(PRInt32 err)
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
 	}
 }
 
 void _MD_os2_map_gethostname_error(PRInt32 err)
 {
     switch (err) {
+#ifdef SOCEFAULT
 		case SOCEFAULT:
 			PR_SetError(PR_ACCESS_FAULT_ERROR, err);
 			break;
+#endif
 		case ENETDOWN:
 		case EINPROGRESS:
 		default:
 			PR_SetError(PR_UNKNOWN_ERROR, err);
 			break;
     }
 }
 
@@ -1011,19 +1043,21 @@ void _MD_os2_map_select_error(PRInt32 er
          * context, ENOTSOCK is equivalent to EBADF on Unix.
          */
         case ENOTSOCK:
             prerror = PR_BAD_DESCRIPTOR_ERROR;
             break;
         case EINVAL:
             prerror = PR_INVALID_ARGUMENT_ERROR;
             break;
+#ifdef SOCEFAULT
         case SOCEFAULT:
             prerror = PR_ACCESS_FAULT_ERROR;
             break;
+#endif
         default:
             prerror = PR_UNKNOWN_ERROR;
     }
     PR_SetError(prerror, err);
 }
 
 void _MD_os2_map_lockf_error(PRInt32 err)
 {
--- a/pr/src/md/os2/os2gc.c
+++ b/pr/src/md/os2/os2gc.c
@@ -17,18 +17,16 @@
  */
 
 /*
  * GC related routines
  *
  */
 #include "primpl.h"
 
-extern APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
-
 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 
 {
     CONTEXTRECORD context;
     context.ContextFlags = CONTEXT_INTEGER;
 
     if (_PR_IS_NATIVE_THREAD(t)) {
         context.ContextFlags |= CONTEXT_CONTROL;
         if (QueryThreadContext(t->md.handle, CONTEXT_CONTROL, &context)) {
--- a/pr/src/md/os2/os2inrval.c
+++ b/pr/src/md/os2/os2inrval.c
@@ -27,18 +27,16 @@ ULONG _os2_ticksPerSec = -1;
 PRIntn _os2_bitShift = 0;
 PRInt32 _os2_highMask = 0;
 
 
    
 PR_IMPLEMENT(void)
 _PR_MD_INTERVAL_INIT()
 {
-   ULONG count;
-
    if (DosTmrQueryFreq(&_os2_ticksPerSec) == NO_ERROR)
    {
       while(_os2_ticksPerSec > PR_INTERVAL_MAX) {
           _os2_ticksPerSec >>= 1;
           _os2_bitShift++;
           _os2_highMask = (_os2_highMask << 1)+1;
       }
    }
--- a/pr/src/md/os2/os2io.c
+++ b/pr/src/md/os2/os2io.c
@@ -18,17 +18,25 @@
 
 /* OS2 IO module
  *
  * Assumes synchronous I/O.
  *
  */
 
 #include "primpl.h"
+#include "prio.h"
+#include <ctype.h>
+#ifdef XP_OS2_VACPP
 #include <direct.h>
+#else
+#include <dirent.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
 
 struct _MDLock               _pr_ioq_lock;
 
 PRStatus
 _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
 {
     PRInt32 rv;
     ULONG count;
@@ -99,38 +107,43 @@ PRInt32
     HFILE file;
     PRInt32 access = OPEN_SHARE_DENYNONE;
     PRInt32 flags = OPEN_ACTION_OPEN_IF_EXISTS;
     PRInt32 rc;
     PRUword actionTaken;
 
     ULONG CurMaxFH = 0;
     LONG ReqCount = 1;
+    ULONG fattr;
  
     if (osflags & PR_RDONLY)
         access |= OPEN_ACCESS_READONLY;
     else if (osflags & PR_WRONLY)
         access |= OPEN_ACCESS_WRITEONLY;
     else if(osflags & PR_RDWR)
         access |= OPEN_ACCESS_READWRITE;
     if (osflags & PR_CREATE_FILE)
         flags |= OPEN_ACTION_CREATE_IF_NEW;
     else if (osflags & PR_TRUNCATE){
         flags &= ~OPEN_ACTION_OPEN_IF_EXISTS;
         flags |= OPEN_ACTION_REPLACE_IF_EXISTS;
     }
-        
+
+    if (isxdigit(mode) == 0) /* file attribs are hex, UNIX modes octal */
+      fattr = ((ULONG)mode == FILE_HIDDEN) ? FILE_HIDDEN : FILE_NORMAL;
+    else fattr = FILE_NORMAL;
+
     /* OS/2 sets the Max file handles per process to 20 by default */
     DosSetRelMaxFH(&ReqCount, &CurMaxFH);
 
     rc = DosOpen((char*)name,
                  &file,            /* file handle if successful */
                  &actionTaken,     /* reason for failure        */
                  0,                /* initial size of new file  */
-                 FILE_NORMAL,      /* file system attributes    */
+                 fattr,            /* file system attributes    */
                  flags,            /* Open flags                */
                  access,           /* Open mode and rights      */
                  0);               /* OS/2 Extended Attributes  */
     if (rc != NO_ERROR) {
 		_PR_MD_MAP_OPEN_ERROR(rc);
       return -1; 
 	}
 
@@ -185,47 +198,47 @@ PRInt32
     if (rv == -1) 
        _PR_MD_MAP_WRITE_ERROR(errno);
 #endif
 
     return bytes;
 } /* --- end _PR_MD_WRITE() --- */
 
 PRInt32
-_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, int whence)
+_PR_MD_LSEEK(PRFileDesc *fd, PRInt32 offset, PRSeekWhence whence)
 {
     PRInt32 rv;
     PRUword newLocation;
 
     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, offset, whence, &newLocation);
 
 	if (rv != NO_ERROR) {
 		_PR_MD_MAP_LSEEK_ERROR(rv);
 		return -1;
 	} else
 		return newLocation;
 }
 
 PRInt64
-_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, int whence)
+_PR_MD_LSEEK64(PRFileDesc *fd, PRInt64 offset, PRSeekWhence whence)
 {
     PRInt64 result;
     PRInt32 rv, low = offset.lo, hi = offset.hi;
     PRUword newLocation;
 
     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, low, whence, &newLocation);
     rv = DosSetFilePtr((HFILE)fd->secret->md.osfd, hi, FILE_CURRENT, &newLocation);
 
   	if (rv != NO_ERROR) {
 		_PR_MD_MAP_LSEEK_ERROR(rv);
 		hi = newLocation = -1;
    }
 
-    result.lo = hi;
-    result.hi = newLocation;
+    result.lo = newLocation;
+    result.hi = hi;
 	return result;
 }
 
 PRInt32
 _PR_MD_FSYNC(PRFileDesc *fd)
 {
     PRInt32 rc = DosResetBuffer((HFILE)fd->secret->md.osfd);
 
@@ -247,16 +260,17 @@ PRInt32
  	if (rv != NO_ERROR)
 		_PR_MD_MAP_CLOSE_ERROR(rv);
     return rv;
 }
 
 
 /* --- DIR IO ------------------------------------------------------------ */
 #define GetFileFromDIR(d)       (d)->d_entry.achName
+#define GetFileAttr(d)          (d)->d_entry.attrFile
 
 void FlipSlashes(char *cp, int len)
 {
     while (--len >= 0) {
     if (cp[0] == '/') {
         cp[0] = PR_DIRECTORY_SEPARATOR;
     }
     cp++;
@@ -291,63 +305,78 @@ PRInt32
 
 
 PRStatus
 _PR_MD_OPEN_DIR(_MDDir *d, const char *name)
 {
     char filename[ CCHMAXPATH ];
     PRUword numEntries, rc;
 
+    numEntries = 1;
+
     PR_snprintf(filename, CCHMAXPATH, "%s%s%s",
                 name, PR_DIRECTORY_SEPARATOR_STR, "*.*");
     FlipSlashes( filename, strlen(filename) );
 
     d->d_hdl = HDIR_CREATE;
 
-    rc = DosFindFirst( filename, &d->d_hdl, FILE_DIRECTORY, &(d->d_entry), sizeof(d->d_entry), &numEntries, FIL_STANDARD); 
+    rc = DosFindFirst( filename,
+                       &d->d_hdl,
+                       FILE_DIRECTORY | FILE_HIDDEN,
+                       &(d->d_entry),
+                       sizeof(d->d_entry),
+                       &numEntries,
+                       FIL_STANDARD);
     if ( rc != NO_ERROR ) {
 		_PR_MD_MAP_OPENDIR_ERROR(rc);
         return PR_FAILURE;
     }
     d->firstEntry = PR_TRUE;
     d->magic = _MD_MAGIC_DIR;
     return PR_SUCCESS;
 }
 
 char *
 _PR_MD_READ_DIR(_MDDir *d, PRIntn flags)
 {
     PRUword numFiles = 1;
     BOOL rv;
     char *fileName;
+    USHORT fileAttr;
 
     if ( d ) {
        while (1) {
            if (d->firstEntry) {
                d->firstEntry = PR_FALSE;
                rv = NO_ERROR;
            } else {
-               rv = DosFindNext(d->d_hdl, &(d->d_entry), sizeof(d->d_entry), &numFiles);
+               rv = DosFindNext(d->d_hdl,
+                                &(d->d_entry),
+                                sizeof(d->d_entry),
+                                &numFiles);
            }
            if (rv != NO_ERROR) {
                break;
            }
            fileName = GetFileFromDIR(d);
+           fileAttr = GetFileAttr(d);
            if ( (flags & PR_SKIP_DOT) &&
                 (fileName[0] == '.') && (fileName[1] == '\0'))
                 continue;
            if ( (flags & PR_SKIP_DOT_DOT) &&
                 (fileName[0] == '.') && (fileName[1] == '.') &&
                 (fileName[2] == '\0'))
                 continue;
 			/*
 			 * XXX
 			 * Is this the correct definition of a hidden file on OS/2?
 			 */
-           if ( (flags & PR_SKIP_HIDDEN) && (fileName[0] == '.'))
+           if ((flags & PR_SKIP_NONE) && (fileAttr & FILE_HIDDEN))
+                return fileName;
+           else if ((flags & PR_SKIP_HIDDEN) && (fileAttr & FILE_HIDDEN))
                 continue;
            return fileName;
         }
         PR_ASSERT(NO_ERROR != rv);
 			_PR_MD_MAP_READDIR_ERROR(rv);
         return NULL;
 		}
     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
@@ -365,18 +394,22 @@ PRInt32
         return -1;
     }
 }
 
 PRInt32
 _PR_MD_STAT(const char *fn, struct stat *info)
 {
     PRInt32 rv;
+    char filename[CCHMAXPATH];
 
-    rv = _stat((char*)fn, info);
+    PR_snprintf(filename, CCHMAXPATH, "%s", fn);
+    FlipSlashes(filename, strlen(filename));
+
+    rv = _stat((char*)filename, info);
     if (-1 == rv) {
         /*
          * Check for MSVC runtime library _stat() bug.
          * (It's really a bug in FindFirstFile().)
          * If a pathname ends in a backslash or slash,
          * e.g., c:\temp\ or c:/temp/, _stat() will fail.
          * Note: a pathname ending in a slash (e.g., c:/temp/)
          * can be handled by _stat() on NT but not on Win95.
@@ -504,19 +537,19 @@ PRInt32
         return 0;
     } else {
 		_PR_MD_MAP_RENAME_ERROR(rc);
         return -1;
     }
 }
 
 PRInt32
-_PR_MD_ACCESS(const char *name, PRIntn how)
+_PR_MD_ACCESS(const char *name, PRAccessHow how)
 {
-PRInt32 rv;
+  PRInt32 rv;
     switch (how) {
       case PR_ACCESS_WRITE_OK:
         rv = access(name, 02);
 		break;
       case PR_ACCESS_READ_OK:
         rv = access(name, 04);
 		break;
       case PR_ACCESS_EXISTS:
@@ -531,17 +564,17 @@ PRInt32 rv;
     return rv;
 }
 
 PRInt32
 _PR_MD_MKDIR(const char *name, PRIntn mode)
 {
    PRInt32 rc;
     /* XXXMB - how to translate the "mode"??? */
-    if ((rc = DosCreateDir((char *)name, NULL)) == NO_ERROR) {
+    if ((rc = DosCreateDir((char *)name, NULL))== NO_ERROR) {
         return 0;
     } else {
 		_PR_MD_MAP_MKDIR_ERROR(rc);
         return -1;
     }
 }
 
 PRInt32
--- a/pr/src/md/os2/os2misc.c
+++ b/pr/src/md/os2/os2misc.c
@@ -15,16 +15,17 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 /*
  * os2misc.c
  *
  */
+#include <string.h>
 #include "primpl.h"
 
 char *
 _PR_MD_GET_ENV(const char *name)
 {
     return getenv(name);
 }
 
@@ -330,18 +331,16 @@ PRProcess * _PR_CreateOS2Process(
        qsort((void *) newEnvp, (size_t) numEnv, sizeof(char *), compare);
    }
    if (assembleEnvBlock(newEnvp, &envBlock) == -1) {
        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
        goto errorExit;
    }
 
    if (attr) {
-       PRBool redirected = PR_FALSE;
-
       /* On OS/2, there is really no way to pass file handles for stdin, stdout, 
        * and stderr to a new process.  Instead, we can make it a child process       
        * and make the given file handles a copy of our stdin, stdout, and stderr.
        * The child process then inherits ours, and we set ours back.  Twisted
        * and gross I know. If you know a better way, please use it.
        */
        if (attr->stdinFd) {
             hStdIn = (HFILE) attr->stdinFd->secret->md.osfd;
@@ -429,17 +428,17 @@ PRStatus _PR_WaitOS2Process(PRProcess *p
     RESULTCODES results;
     PID pidEnded = 0;
 
     ulRetVal = DosWaitChild(DCWA_PROCESS, DCWW_WAIT, 
                             &results,
                             &pidEnded, process->md.pid);
 
     if (ulRetVal != NO_ERROR) {
-       printf("\nDosWaitChild rc = %i\n", ulRetVal);
+       printf("\nDosWaitChild rc = %lu\n", ulRetVal);
         PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
         return PR_FAILURE;
     }
     PR_DELETE(process);
     return PR_SUCCESS;
 }
 
 PRStatus _PR_KillOS2Process(PRProcess *process)
@@ -450,17 +449,16 @@ PRStatus _PR_KillOS2Process(PRProcess *p
     }
     PR_SetError(PR_UNKNOWN_ERROR, ulRetVal);
     return PR_FAILURE;
 }
 
 PRStatus _MD_OS2GetHostName(char *name, PRUint32 namelen)
 {
     PRIntn rv;
-    PRInt32 syserror;
 
     rv = gethostname(name, (PRInt32) namelen);
     if (0 == rv) {
         return PR_SUCCESS;
     }
 	_PR_MD_MAP_GETHOSTNAME_ERROR(sock_errno());
     return PR_FAILURE;
 }
--- a/pr/src/md/os2/os2poll.c
+++ b/pr/src/md/os2/os2poll.c
@@ -15,16 +15,20 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 /*
  * This file implements _PR_MD_PR_POLL for OS/2.
  */
 
+#ifdef XP_OS2_EMX
+	#include <sys/time.h> /* For timeval. */
+#endif
+
 #include "primpl.h"
 
 PRInt32 _PR_MD_PR_POLL(
     PRPollDesc *pds, PRIntn npds, PRIntervalTime timeout)
 {
     PRInt32 osfd;
     int maxfd = -1;
     fd_set rd, wt, ex;
--- a/pr/src/md/os2/os2sock.c
+++ b/pr/src/md/os2/os2sock.c
@@ -23,16 +23,20 @@
 /*Note from DSR111297 - it should be noted that there are two flavors of select() on OS/2    */
 /*There is standard BSD (which is kind of slow) and a new flavor of select() that takes      */
 /*an integer list of sockets, the number of read sockets, write sockets, except sockets, and */
 /*a millisecond count for timeout. In the interest of performance I have choosen the OS/2    */
 /*specific version of select(). See OS/2 TCP/IP Programmer's Toolkit for more info.          */ 
 
 #include "primpl.h"
 
+#ifdef XP_OS2_EMX
+    #include <sys/time.h> /* For timeval. */
+#endif
+
 void
 _PR_MD_INIT_IO()
 {
     sock_init();
 }
 
 /* --- SOCKET IO --------------------------------------------------------- */
 
@@ -202,17 +206,17 @@ PRInt32
 #else
     int socks[1]; 
     long lTimeout = -1;
 #endif
 
     if ((rv = connect(osfd, (struct sockaddr *) addr, addrlen)) == -1) 
     {
         err = sock_errno();
-        if ((!fd->secret->nonblocking) && (err == EINPROGRESS) || (err == EWOULDBLOCK))
+        if ((!fd->secret->nonblocking) && ((err == EINPROGRESS) || (err == EWOULDBLOCK)))
         {
 #ifdef BSD_SELECT
            if (timeout == PR_INTERVAL_NO_TIMEOUT)
                tvp = NULL;
             else 
             {
                 tv.tv_sec = PR_IntervalToSeconds(timeout);
                 tv.tv_usec = PR_IntervalToMicroseconds(
@@ -286,17 +290,16 @@ PRInt32
     return rv;
 }
 
 
 PRInt32
 _PR_MD_BIND(PRFileDesc *fd, const PRNetAddr *addr, PRUint32 addrlen)
 {
     PRInt32 rv;
-    int one = 1;
 
     rv = bind(fd->secret->md.osfd, (struct sockaddr*) &(addr->inet), addrlen);
 
     if (rv == -1)  {
 		_PR_MD_MAP_BIND_ERROR(sock_errno());
         return -1;
 	}
 
--- a/pr/src/md/os2/os2thred.c
+++ b/pr/src/md/os2/os2thred.c
@@ -14,24 +14,31 @@
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 #include "primpl.h"
 #include <process.h>  /* for _beginthread() */
 
-APIRET (* APIENTRY QueryThreadContext)(OS2TID, ULONG, PCONTEXTRECORD);
+#ifdef XP_OS2_VACPP
+#include <time.h>     /* for _tzset() */
+#endif
+
+/* --- Declare these to avoid "implicit" warnings --- */
+PR_EXTERN(void) _PR_MD_NEW_SEM(_MDSemaphore *md, PRUintn value);
+PR_EXTERN(void) _PR_MD_DESTROY_SEM(_MDSemaphore *md);
 
 /* --- globals ------------------------------------------------ */
 _NSPR_TLS*        pThreadLocalStorage = 0;
 _PRInterruptTable             _pr_interruptTable[] = { { 0 } };
+APIRET (* APIENTRY QueryThreadContext)(TID, ULONG, PCONTEXTRECORD);
 
 PR_IMPLEMENT(void)
-_PR_MD_ENSURE_TLS()
+_PR_MD_ENSURE_TLS(void)
 {
    if(!pThreadLocalStorage)
    {
       /* Allocate thread local storage (TLS).  Note, that only 32 bytes can
        * be allocated at a time. 
        */
       int rc = DosAllocThreadLocalMemory(sizeof(_NSPR_TLS) / 4, (PULONG*)&pThreadLocalStorage);
       PR_ASSERT(rc == NO_ERROR);
@@ -42,16 +49,20 @@ PR_IMPLEMENT(void)
 PR_IMPLEMENT(void)
 _PR_MD_EARLY_INIT()
 {
    HMODULE hmod;
 
    if (DosLoadModule(NULL, 0, "DOSCALL1.DLL", &hmod) == 0)
        DosQueryProcAddr(hmod, 877, "DOSQUERYTHREADCONTEXT",
                         (PFN *)&QueryThreadContext);
+
+#ifdef XP_OS2_VACPP
+   _tzset();
+#endif
 }
 
 PR_IMPLEMENT(void)
 _PR_MD_INIT_PRIMORDIAL_THREAD(PRThread *thread)
 {
    PTIB ptib;
    PPIB ppib;
    PRUword rc;
@@ -60,35 +71,33 @@ PR_IMPLEMENT(void)
 
    thread->md.handle = ptib->tib_ptib2->tib2_ultid;
 }
 
 
 PR_IMPLEMENT(PRStatus)
 _PR_MD_INIT_THREAD(PRThread *thread)
 {
-   APIRET rc;
-
    if (thread->flags & _PR_PRIMORDIAL)
       _PR_MD_INIT_PRIMORDIAL_THREAD(thread);
 
    /* Create the blocking IO semaphore */
    _PR_MD_NEW_SEM(&thread->md.blocked_sema, 1);
-   return (thread->md.blocked_sema.sem != NULL) ? PR_SUCCESS : PR_FAILURE;
+   return (thread->md.blocked_sema.sem != 0) ? PR_SUCCESS : PR_FAILURE;
 }
 
 PR_IMPLEMENT(PRStatus) 
 _PR_MD_CREATE_THREAD(PRThread *thread, 
                   void (*start)(void *), 
                   PRThreadPriority priority, 
                   PRThreadScope scope, 
                   PRThreadState state, 
                   PRUint32 stackSize)
 {
-    thread->md.handle = thread->id = (OS2TID) _beginthread(
+    thread->md.handle = thread->id = (TID) _beginthread(
                     (void(* _Optlink)(void*))start,
                     NULL, 
                     thread->stack->stackSize,
                     thread);
     if(thread->md.handle == -1) {
         return PR_FAILURE;
     }
     _PR_MD_SET_PRIORITY(&(thread->md), priority);
@@ -134,18 +143,24 @@ PR_IMPLEMENT(void)
                 ("PR_SetThreadPriority: can't set thread priority\n"));
     }
     return;
 }
 
 PR_IMPLEMENT(void)
 _PR_MD_CLEAN_THREAD(PRThread *thread)
 {
-   /* Just call _PR_MD_EXIT_THREAD for now */
-   _PR_MD_EXIT_THREAD(thread);
+	if (&thread->md.blocked_sema) {
+	  _PR_MD_DESTROY_SEM(&thread->md.blocked_sema);
+	}
+	
+	if (thread->md.handle) {
+	  DosKillThread(thread->md.handle);
+	  thread->md.handle = 0;
+	}
 }
 
 PR_IMPLEMENT(void)
 _PR_MD_EXIT_THREAD(PRThread *thread)
 {
     _PR_MD_DESTROY_SEM(&thread->md.blocked_sema);
 
     if (thread->md.handle) {
@@ -155,17 +170,19 @@ PR_IMPLEMENT(void)
         *
         * DosKillThread will not kill the current thread, instead we must use
         * DosExit.
         */
        if ( thread != _MD_CURRENT_THREAD() ) {
            DosKillThread( thread->md.handle );
            DosResumeThread( thread->md.handle );
        } else {
+#ifndef XP_OS2_EMX
            _endthread();
+#endif
        }
        thread->md.handle = 0;
     }
 
     _PR_MD_SET_CURRENT_THREAD(NULL);
 }
 
 
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -291,20 +291,28 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByName(
         h = gethostbyname2(name, AF_INET6);
         if (NULL == h)
         {
             h = gethostbyname2(name, AF_INET);
         }
     }
     else
     {
+#ifdef XP_OS2_VACPP
+	    h = gethostbyname((char *)name);
+#else
         h = gethostbyname(name);
+#endif
     }
 #else
+#ifdef XP_OS2_VACPP
+	h = gethostbyname((char *)name);
+#else
     h = gethostbyname(name);
+#endif
 #endif /* _PR_INET6 */
     
 	if (NULL == h)
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 	else
 	{
 		rv = CopyHostent(h, buf, bufsize, hp);
 		if (PR_SUCCESS != rv)
@@ -342,18 +350,21 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
 	}
 	else
 #endif /* defined(_PR_INET6) */
 	{
 		PR_ASSERT(hostaddr->raw.family == AF_INET);
 		addr = &hostaddr->inet.ip;
 		addrlen = sizeof(hostaddr->inet.ip);
 	}
-
+#ifdef XP_OS2_VACPP
+	h = gethostbyaddr((char *)addr, addrlen, hostaddr->raw.family);
+#else
 	h = gethostbyaddr(addr, addrlen, hostaddr->raw.family);
+#endif
 	if (NULL == h) PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 	else
 	{
 		rv = CopyHostent(h, buf, bufsize, hostentry);
 		if (PR_SUCCESS != rv) {
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
 		}
 	}
@@ -377,17 +388,21 @@ PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
  * This may seem like a silly thing to do, but the compiler SHOULD
  * complain if getprotobyname_r() is implemented on some system and
  * we're not using it. For sure these signatures are different than
  * any usable implementation.
  */
 
 static struct protoent *getprotobyname_r(const char* name)
 {
+#ifdef XP_OS2_VACPP
+	return getprotobyname((char *)name);
+#else
 	return getprotobyname(name);
+#endif
 } /* getprotobyname_r */
 
 static struct protoent *getprotobynumber_r(PRInt32 number)
 {
 	return getprotobynumber(number);
 } /* getprotobynumber_r */
 
 #endif /* !defined(_PR_HAVE_GETPROTO_R) */
@@ -716,17 +731,21 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAdd
             status = PR_FAILURE;
         }
     }
     else
 #endif
     {
 	    PRUint32 *ip = (PRUint32*)&addr->inet.ip;
 
+#ifdef XP_OS2_VACPP
+        *ip = inet_addr((char *)string);
+#else
         *ip = inet_addr(string);
+#endif
 	    if ((PRUint32) -1 == *ip)
         {
             /*
              * Either the af argument is not AF_INET, or the string argument
              * is a malformed address string.
              */
             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
             status = PR_FAILURE;
--- a/pr/src/misc/prsystem.c
+++ b/pr/src/misc/prsystem.c
@@ -75,16 +75,31 @@ PR_IMPLEMENT(PRStatus) PR_GetSystemInfo(
         /* Return the version of the operating system */
 #if defined(XP_UNIX)
         {
             struct utsname info;
             uname(&info);
             (void)PR_snprintf(buf, buflen, info.release);
         }
 #endif
+#if defined(XP_OS2)
+        {
+            ULONG os2ver[2] = {0};
+            DosQuerySysInfo(QSV_VERSION_MINOR, QSV_VERSION_REVISION,
+                            &os2ver, sizeof(os2ver));
+            /* Formatting for normal usage (2.11, 3.0, 4.0); officially,
+               Warp 4 is version 2.40.00 */
+            if (os2ver[0] < 30)
+              (void)PR_snprintf(buf, buflen, "%s%lu",
+                                "2.", os2ver[0]);
+            else
+              (void)PR_snprintf(buf, buflen, "%lu%s%lu",
+                                os2ver[0]/10, ".", os2ver[1]);
+        }
+#endif /* OS2 */
         break;
 
       case PR_SI_ARCHITECTURE:
         /* Return the architecture of the machine (ie. x86, mips, alpha, ...)*/
         (void)PR_snprintf(buf, buflen, _PR_SI_ARCHITECTURE);
         break;
     }
     return PR_SUCCESS;
--- a/pr/src/misc/prtime.c
+++ b/pr/src/misc/prtime.c
@@ -571,26 +571,31 @@ static struct tm *MT_safe_localtime(cons
      * represents a time before midnight January 1, 1970.  In
      * that case, we also return a NULL pointer and the struct tm
      * object pointed to by 'result' is not modified.
      *
      * Watcom C/C++ 11.0 localtime() treats time_t as unsigned long
      * hence, does not recognize negative values of clock as pre-1/1/70.
      * We have to manually check (WIN16 only) for negative value of
      * clock and return NULL.
+     *
+     * With negative values of clock, emx returns the struct tm for
+     * clock plus ULONG_MAX. So we also have to check for the invalid
+     * structs returned for timezones west of Greenwich when clock == 0.
      */
     
 #if defined(XP_MAC)
     tmPtr = Maclocaltime(clock);
 #else
     tmPtr = localtime(clock);
 #endif
 
-#if defined(WIN16)
-    if ( (PRInt32) *clock < 0 )
+#if defined(WIN16) || defined(XP_OS2_EMX)
+    if ( (PRInt32) *clock < 0 ||
+         ( (PRInt32) *clock == 0 && tmPtr->tm_year != 70))
         result = NULL;
     else
         *result = *tmPtr;
 #else
     if (tmPtr) {
         *result = *tmPtr;
     } else {
         result = NULL;
--- a/pr/tests/Makefile
+++ b/pr/tests/Makefile
@@ -128,16 +128,25 @@ CSRCS =             \
 	tmocon.c        \
 	tpd.c			\
 	version.c	    \
 	udpsrv.c	    \
 	writev.c        \
 	xnotify.c       \
 	$(NULL)
 
+ifeq ($(OS_TARGET),OS2)
+CSRCS +=            \
+	servr_uu.c		\
+	sleep.c			\
+	stat.c		    \
+	yield.c         \
+	$(NULL)
+endif
+
 ifeq ($(OS_ARCH), WINNT)
 PROG_SUFFIX = .exe
 else
 PROG_SUFFIX =
 endif
 
 PROGS = $(addprefix $(OBJDIR)/, $(CSRCS:.c=$(PROG_SUFFIX)))
 
@@ -152,20 +161,24 @@ LIBPR = -lnspr$(MOD_VERSION)
 LIBPLC = -lplc$(MOD_VERSION)
 
 ifeq ($(OS_ARCH), WINNT)
 ifeq ($(OS_TARGET), WIN16)
   LIBPR = $(DIST)/lib/nspr$(MOD_VERSION).lib
   LIBPLC= $(DIST)/lib/plc$(MOD_VERSION).lib
 else
 ifeq ($(OS_TARGET), OS2)
-  LDOPTS = -NOE -DEBUG -nologo -PMTYPE:VIO
+ifdef XP_OS2_VACPP
+  LDOPTS =
   LIBPR = $(DIST)/lib/nspr$(MOD_VERSION).lib
   LIBPLC= $(DIST)/lib/plc$(MOD_VERSION).lib
 else
+  LDOPTS = -Zlinker /PM:VIO
+endif
+else
   LDOPTS = -NOLOGO -DEBUG -DEBUGTYPE:CV -INCREMENTAL:NO
   LIBPR = $(DIST)/lib/libnspr$(MOD_VERSION).$(LIB_SUFFIX)
   LIBPLC= $(DIST)/lib/libplc$(MOD_VERSION).$(LIB_SUFFIX)
 endif
 endif
 endif
 
 ifneq ($(OS_ARCH), WINNT)
@@ -418,17 +431,17 @@ ifeq ($(OS_TARGET),WIN16)
 	echo $(W16STDIO) >>w16link
 	echo library  >>w16link
 	echo $(LIBPR),	     >>w16link
 	echo $(LIBPLC),		 >>w16link
 	echo winsock.lib     >>w16link
 	wlink @w16link.
 else
 ifeq ($(OS_TARGET),OS2)
-	$(LINK) $(LDOPTS) $< $(LIBPLC) $(LIBPR) so32dll.lib tcp32dll.lib -MAP:$(@:.exe=.map) -out:$@
+	$(LINK) $(EXEFLAGS) $(LDOPTS) $< $(LIBPLC) $(LIBPR) $(OS_LIBS) $(EXTRA_LIBS)
 else
 	link $(LDOPTS) $< $(LIBPLC) $(LIBPR) wsock32.lib -out:$@
 endif
 endif
 else
 	$(CC) $(XCFLAGS) $< $(LDOPTS) $(LIBPLC) $(LIBPR) $(EXTRA_LIBS) -o $@
 endif
 
--- a/pr/tests/attach.c
+++ b/pr/tests/attach.c
@@ -59,16 +59,17 @@
 #include <sys/wait.h>
 #include <errno.h>
 #elif defined(SOLARIS)
 #include <thread.h>
 #elif defined(OS2)
 #define INCL_DOS
 #define INCL_ERRORS
 #include <os2.h>
+#include <process.h>
 #endif
 
 #define DEFAULT_COUNT 1000
 PRIntn failed_already=0;
 PRIntn debug_mode;
 
 
 int count;
--- a/pr/tests/ipv6.c
+++ b/pr/tests/ipv6.c
@@ -119,17 +119,17 @@ PRIntn main(PRIntn argc, char **argv)
             Help();  /* so give him an earful */
             return 2;  /* but not a lot else */
         }
     }
     PL_DestroyOptState(opt);
 
     if (version)
     {
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) || defined(XP_OS2)
 #define NSPR_LIB "nspr21"
 #elif defined(WIN32)
 #define NSPR_LIB "libnspr21"
 #else
 #error "Architecture not supported"
 #endif
         const PRVersionDescription *version_info;
         char *nspr_path = PR_GetEnv("LD_LIBRARY_PATH");
@@ -208,16 +208,17 @@ PRIntn main(PRIntn argc, char **argv)
         {
             failed = PR_TRUE;
             PL_FPrintError(err, "PR_GetHostByName");
         }
         else
         {
             PRIntn index = 0;
             PRNetAddr address;
+            memset(&address, 0, sizeof(PRNetAddr));
             PR_fprintf(err, "success .. enumerating results\n");
             do
             {
                 index = PR_EnumerateHostEnt(index, &host, 0, &address);
                 if (index > 0) PrintAddress(&address);
                 else if (-1 == index)
                 {
                     failed = PR_TRUE;
--- a/pr/tests/op_filok.c
+++ b/pr/tests/op_filok.c
@@ -45,31 +45,35 @@
 /*
  * The name of a file that is guaranteed to exist
  * 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"
 #else
 #error "Unknown OS"
 #endif
 
 static PRFileDesc *t1;
 
 int main(int argc, char **argv)
 {
 
 #ifdef XP_MAC
 	SetupMacPrintfLog("pr_open_re.log");
 #endif
 	
     PR_STDIO_INIT();
+
 	t1 = PR_Open(EXISTING_FILENAME, PR_RDONLY, 0666);
+
 	if (t1 == NULL) {
 		printf ("error code is %d \n", PR_GetError());
 		printf ("File %s should be found\n",
 				EXISTING_FILENAME);
 		return 1;
 	} else {
 		if (PR_Close(t1) == PR_SUCCESS) {
 			printf ("Test passed \n");
--- a/pr/tests/sel_spd.c
+++ b/pr/tests/sel_spd.c
@@ -194,17 +194,17 @@ void
 
 		if ( (newsock = PR_Accept(sock, &sa,
 					PR_INTERVAL_NO_TIMEOUT)) == NULL) {
 			fprintf(stderr, "Error accepting connection %d in server thread %d\n",
 				index, *id);
 			goto done;
 		}
 #ifdef DEBUG
-	fprintf(stdout, "server thread %d got connection\n", *id, newsock);
+	fprintf(stdout, "server thread %d got connection %d\n", *id, newsock);
 #endif
 
 
 		connect_done = PR_IntervalNow();
 		
 		if ( _readn(newsock, data_buffer, _client_data) < _client_data) {
 			fprintf(stderr, "Error reading client data for iteration %d in server thread %d\n", index, *id );
 			goto done;
@@ -427,22 +427,22 @@ static void Measure(void (*func)(void), 
     d = (double)PR_IntervalToMicroseconds(stop - start);
 
     printf("%40s: %6.2f usec\n", msg, d / _iterations);
 }
 
 
 main(int argc, char **argv)
 {
-#ifdef XP_UNIX
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
 	int opt;
 	extern char *optarg;
 #endif
 
-#ifdef XP_UNIX
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
 	while ( (opt = getopt(argc, argv, "c:s:i:t:v")) != EOF) {
 		switch(opt) {
 			case 'i':
 				_iterations = atoi(optarg);
 				break;
 			case 't':
 				_threads_max = _threads = atoi(optarg);
 				break;
--- a/pr/tests/select2.c
+++ b/pr/tests/select2.c
@@ -36,16 +36,17 @@
 /* Used to get the command line option */
 #include "plgetopt.h"
 #include "prttools.h"
 #include "primpl.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/time.h>
 
 #define PORT 8000
 #define DEFAULT_COUNT 10
 PRInt32 count;
 
 
 /***********************************************************************
 ** PRIVATE FUNCTION:    Test_Result
--- a/pr/tests/servr_kk.c
+++ b/pr/tests/servr_kk.c
@@ -62,17 +62,16 @@ static PRThreadScope ServerScope, Client
 #define SERVER_STATE_STARTUP 0
 #define SERVER_STATE_READY   1
 #define SERVER_STATE_DYING   2
 #define SERVER_STATE_DEAD    4
 int       ServerState;
 PRLock    *ServerStateCVLock;
 PRCondVar *ServerStateCV;
 
-#undef DEBUGPRINTS
 #ifdef DEBUGPRINTS
 #define DPRINTF printf
 #else
 #define DPRINTF
 #endif
 
 PRIntn failed_already=0;
 PRIntn debug_mode;
--- a/pr/tests/servr_ku.c
+++ b/pr/tests/servr_ku.c
@@ -62,17 +62,16 @@ static PRThreadScope ServerScope, Client
 #define SERVER_STATE_STARTUP 0
 #define SERVER_STATE_READY   1
 #define SERVER_STATE_DYING   2
 #define SERVER_STATE_DEAD    4
 int       ServerState;
 PRLock    *ServerStateCVLock;
 PRCondVar *ServerStateCV;
 
-#undef DEBUGPRINTS
 #ifdef DEBUGPRINTS
 #define DPRINTF printf
 #else
 #define DPRINTF
 #endif
 
 PRIntn failed_already=0;
 PRIntn debug_mode;
--- a/pr/tests/servr_uk.c
+++ b/pr/tests/servr_uk.c
@@ -62,17 +62,16 @@ static PRThreadScope ServerScope, Client
 #define SERVER_STATE_STARTUP 0
 #define SERVER_STATE_READY   1
 #define SERVER_STATE_DYING   2
 #define SERVER_STATE_DEAD    4
 int       ServerState;
 PRLock    *ServerStateCVLock;
 PRCondVar *ServerStateCV;
 
-#undef DEBUGPRINTS
 #ifdef DEBUGPRINTS
 #define DPRINTF printf
 #else
 #define DPRINTF
 #endif
 
 PRIntn failed_already=0;
 PRIntn debug_mode;
--- a/pr/tests/servr_uu.c
+++ b/pr/tests/servr_uu.c
@@ -62,17 +62,16 @@ static PRThreadScope ServerScope, Client
 #define SERVER_STATE_STARTUP 0
 #define SERVER_STATE_READY   1
 #define SERVER_STATE_DYING   2
 #define SERVER_STATE_DEAD    4
 int       ServerState;
 PRLock    *ServerStateCVLock;
 PRCondVar *ServerStateCV;
 
-#undef DEBUGPRINTS
 #ifdef DEBUGPRINTS
 #define DPRINTF printf
 #else
 #define DPRINTF
 #endif
 
 PRIntn failed_already=0;
 PRIntn debug_mode;
--- a/pr/tests/sleep.c
+++ b/pr/tests/sleep.c
@@ -13,29 +13,36 @@
  * 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 "nspr.h"
 
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) || defined(XP_OS2)
 
 #include <stdio.h>
 
+#ifndef XP_OS2
 #include <unistd.h>
+#endif
 #include <sys/time.h>
 
 #if defined(HAVE_SVID_GETTOD)
 #define GTOD(_a) gettimeofday(_a)
 #else
 #define GTOD(_a) gettimeofday((_a), NULL)
 #endif
 
+#if defined (XP_OS2_VACPP)
+#define INCL_DOSPROCESS
+#include <os2.h>
+#endif
+
 static PRIntn rv = 0;
 
 static void Other(void *unused)
 {
     PRIntn didit = 0;
     while (PR_SUCCESS == PR_Sleep(PR_MillisecondsToInterval(250)))
     {
         fprintf(stderr, ".");
--- a/pr/tests/stat.c
+++ b/pr/tests/stat.c
@@ -13,47 +13,59 @@
  * 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.
  */
 
 /*
  * Program to test different ways to get file info; right now it 
- * only works for solaris.
+ * only works for solaris and OS/2.
  *
  */
 #include "nspr.h"
 #include "prpriv.h"
 #include "prinrval.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
+#ifdef XP_OS2
+#include <io.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#endif
+
 #define DEFAULT_COUNT 100000
 PRInt32 count;
 
+#ifndef XP_PC
+char *filename = "/etc/passwd";
+#else
+char *filename = "..\\stat.c";
+#endif
+
 static void statPRStat(void)
 {
     PRFileInfo finfo;
     PRInt32 index = count;
  
     for (;index--;) {
-         PR_GetFileInfo("/etc/passwd", &finfo);
+         PR_GetFileInfo(filename, &finfo);
     }
 }
 
 static void statStat(void)
 {
     struct stat finfo;
     PRInt32 index = count;
  
     for (;index--;) {
-        stat("/etc/passwd", &finfo);
+        stat(filename, &finfo);
     }
 }
 
 /************************************************************************/
 
 static void Measure(void (*func)(void), const char *msg)
 {
     PRIntervalTime start, stop;
--- a/pr/tests/strod.c
+++ b/pr/tests/strod.c
@@ -22,17 +22,17 @@
 #include "prdtoa.h"
 #include "plgetopt.h"
 
 #include <stdlib.h>
 
 static void Help(void)
 {
     PRFileDesc *err = PR_GetSpecialFD(PR_StandardError);
-    PR_fprintf(err, "Usage: /.strod [-c n] [-l n] [-h]\n");
+    PR_fprintf(err, "Usage: /.strod [-n n] [-l n] [-h]\n");
     PR_fprintf(err, "\t-n n Number to translate    (default: 1234567890123456789)\n");
     PR_fprintf(err, "\t-l n Times to loop the test (default: 1)\n");
     PR_fprintf(err, "\t-h   This message and nothing else\n");
 }  /* Help */
 
 static PRIntn PR_CALLBACK RealMain(PRIntn argc, char **argv)
 {
     PLOptStatus os;
--- a/pr/tests/testfile.c
+++ b/pr/tests/testfile.c
@@ -21,16 +21,24 @@
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #ifdef WIN32
 #include <windows.h>
 #endif
 
+#if defined(XP_OS2)
+#define INCL_DOSFILEMGR
+#include <os2.h>
+#ifdef XP_OS2_EMX
+#include <getopt.h>
+#endif /* XP_OS2_EMX */
+#endif /* XP_OS2 */
+
 static int _debug_on = 0;
 
 #ifdef XP_MAC
 #include "prlog.h"
 #include "primpl.h"
 #define printf PR_LogPrint
 #define setbuf(x,y)
 extern void SetupMacPrintfLog(char *logFile);
@@ -63,17 +71,21 @@ typedef struct buffer {
 typedef struct File_Rdwr_Param {
 	char	*pathname;
 	char	*buf;
 	int	offset;
 	int	len;
 } File_Rdwr_Param;
 
 #ifdef XP_PC
+#ifdef XP_OS2
+char *TEST_DIR = "prdir";
+#else
 char *TEST_DIR = "C:\\temp\\prdir";
+#endif
 char *FILE_NAME = "pr_testfile";
 char *HIDDEN_FILE_NAME = "hidden_pr_testfile";
 #else
 char *TEST_DIR = "/tmp/testfile_dir";
 char *FILE_NAME = "pr_testfile";
 char *HIDDEN_FILE_NAME = ".hidden_pr_testfile";
 #endif
 buffer *in_buf, *out_buf;
@@ -486,17 +498,17 @@ HANDLE hfile;
 		if (fd_file == NULL) {
 			printf(
 					"testfile failed to create/open file %s [%d, %d]\n",
 					pathname, PR_GetError(), PR_GetOSError());
 			return -1;
 		}
         PR_Close(fd_file);
 	}
-#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32))
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2)
 	/*
 	 * Create a hidden file - a platform-dependent operation
 	 */
 	strcpy(pathname, TEST_DIR);
 	strcat(pathname, "/");
 	strcat(pathname, HIDDEN_FILE_NAME);
 #if defined(XP_UNIX) || defined(XP_MAC)
 	DPRINTF(("Creating hidden test file %s\n",pathname));
@@ -569,16 +581,26 @@ HANDLE hfile;
 						NULL);
 	if (hfile == INVALID_HANDLE_VALUE) {
 		printf("testfile failed to create/open hidden file %s [0, %d]\n",
 				pathname, GetLastError());
 		return -1;
 	}
 	CloseHandle(hfile);
 						
+#elif defined(OS2)
+	DPRINTF(("Creating hidden test file %s\n",pathname));
+	fd_file = PR_Open(pathname, PR_RDWR | PR_CREATE_FILE, (int)FILE_HIDDEN);
+
+	if (fd_file == NULL) {
+		printf("testfile failed to create/open hidden file %s [%d, %d]\n",
+				pathname, PR_GetError(), PR_GetOSError());
+		return -1;
+	}
+	PR_Close(fd_file);
 #endif	/* XP _UNIX || XP_MAC*/
 
 #endif	/* XP_UNIX || XP_MAC ||(XP_PC && WIN32) */
 
 
 	if (PR_FAILURE == PR_CloseDir(fd_dir))
 	{
 		printf(
@@ -593,17 +615,17 @@ HANDLE hfile;
 			TEST_DIR, PR_GetError(), PR_GetOSError());
 		return -1;
 	}
   
 	/*
 	 * List all files, including hidden files
 	 */
 	DPRINTF(("Listing all files in directory %s\n",TEST_DIR));
-#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32))
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2)
 	num_files = FILES_IN_DIR + 1;
 #else
 	num_files = FILES_IN_DIR;
 #endif
 	while ((dirEntry = PR_ReadDir(fd_dir, PR_SKIP_BOTH)) != NULL) {
 		num_files--;
 		strcpy(pathname, TEST_DIR);
 		strcat(pathname, "/");
@@ -629,17 +651,17 @@ HANDLE hfile;
 		printf(
 			"testfile failed to find all files in directory %s [%d, %d]\n",
 			TEST_DIR, PR_GetError(), PR_GetOSError());
 		return -1;
 	}
 
     PR_CloseDir(fd_dir);
 
-#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32))
+#if defined(XP_UNIX) || defined(XP_MAC) || (defined(XP_PC) && defined(WIN32)) || defined(XP_OS2)
 
 	/*
 	 * List all files, except hidden files
 	 */
 
 	fd_dir = PR_OpenDir(TEST_DIR);
 	if (fd_dir == NULL) {
 		printf(
@@ -747,22 +769,22 @@ HANDLE hfile;
 /************************************************************************/
 
 /*
  * Test file and directory NSPR APIs
  */
 
 int main(int argc, char **argv)
 {
-#ifdef XP_UNIX
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
         int opt;
         extern char *optarg;
 	extern int optind;
 #endif
-#ifdef XP_UNIX
+#if defined(XP_UNIX) || defined(XP_OS2_EMX)
         while ((opt = getopt(argc, argv, "d")) != EOF) {
                 switch(opt) {
                         case 'd':
                                 _debug_on = 1;
                                 break;
                         default:
                                 break;
                 }
--- a/pr/tests/tmocon.c
+++ b/pr/tests/tmocon.c
@@ -42,17 +42,17 @@
 #include "plerror.h"
 #include "plgetopt.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
 /* for getcwd */
-#if defined(XP_UNIX)
+#if defined(XP_UNIX) || defined (XP_OS2_EMX)
 #include <unistd.h>
 #elif defined(XP_PC)
 #include <direct.h>
 #endif
 
 #ifdef XP_MAC
 #include "prlog.h"
 #define printf PR_LogPrint