fixup commit for branch 'travisWebshell_20000308_BRANCH' travisWebshell_20000308_BRANCH
authorcvs2hg
Fri, 18 Feb 2000 16:17:40 +0000
branchtravisWebshell_20000308_BRANCH
changeset 1196 aa34eb64f82b
parent 1054 483e317ac4c0
push idunknown
push userunknown
push dateunknown
fixup commit for branch 'travisWebshell_20000308_BRANCH'
Makefile
Makefile.in
config/Linux.mk
config/module.df
config/prdepend.h
config/rules.mk
configure
configure.in
lib/Makefile
lib/Makefile.in
lib/ds/MANIFEST
lib/ds/Makefile
lib/ds/Makefile.in
lib/ds/plds.rc
lib/ds/plevent.c
lib/ds/plevent.h
lib/ds/plvrsion.c
lib/libc/src/plc.rc
lib/libc/src/plvrsion.c
lib/prstreams/plvrsion.c
lib/prstreams/prstrms.cpp
lib/prstreams/prstrms.h
lib/prstreams/prstrms.rc
macbuild/NSPR20PPC.mcp
makefile.win
pr/include/MANIFEST
pr/include/md/_aix.h
pr/include/md/_aix32.cfg
pr/include/md/_aix32in6.cfg
pr/include/md/_aix64.cfg
pr/include/md/_beos.h
pr/include/md/_hpux.h
pr/include/md/_hpux32.cfg
pr/include/md/_hpux64.cfg
pr/include/md/_irix.h
pr/include/md/_irix32.cfg
pr/include/md/_irix64.cfg
pr/include/md/_linux.cfg
pr/include/md/_linux.h
pr/include/md/_macos.h
pr/include/md/_os2.h
pr/include/md/_osf1.cfg
pr/include/md/_osf1.h
pr/include/md/_solaris.h
pr/include/md/_solaris32.cfg
pr/include/md/_solaris64.cfg
pr/include/md/_unixos.h
pr/include/md/_unixware7.cfg
pr/include/md/_win95.cfg
pr/include/md/_win95.h
pr/include/md/_winnt.cfg
pr/include/md/_winnt.h
pr/include/nspr.h
pr/include/obsolete/probslet.h
pr/include/obsolete/protypes.h
pr/include/prerr.h
pr/include/prinit.h
pr/include/prio.h
pr/include/pripcsem.h
pr/include/private/pprio.h
pr/include/private/primpl.h
pr/include/prlink_mac.h
pr/include/prlog.h
pr/include/prlong.h
pr/include/prnetdb.h
pr/include/prrng.h
pr/include/prshm.h
pr/include/prtpool.h
pr/include/prvrsion.h
pr/src/Makefile
pr/src/Makefile.in
pr/src/io/Makefile
pr/src/io/Makefile.in
pr/src/io/prdir.c
pr/src/io/prfdcach.c
pr/src/io/prfile.c
pr/src/io/priometh.c
pr/src/io/pripv6.c
pr/src/io/prlayer.c
pr/src/io/prpolevt.c
pr/src/io/prsocket.c
pr/src/linking/prlink.c
pr/src/md/mac/macsocket.h
pr/src/md/mac/macsockotpt.c
pr/src/md/mac/prcpucfg.h
pr/src/md/windows/Makefile
pr/src/md/windows/ntio.c
pr/src/md/windows/ntsec.c
pr/src/md/windows/ntthread.c
pr/src/md/windows/w32ipcsem.c
pr/src/md/windows/w32shm.c
pr/src/md/windows/w95io.c
pr/src/md/windows/w95thred.c
pr/src/md/windows/win32_errors.c
pr/src/misc/prerr.c
pr/src/misc/prerr.et
pr/src/misc/prerr.properties
pr/src/misc/prerror.c
pr/src/misc/prinit.c
pr/src/misc/prnetdb.c
pr/src/misc/prtpool.c
pr/src/nspr.rc
pr/src/prvrsion.c
pr/src/pthreads/ptio.c
pr/src/pthreads/ptsynch.c
pr/src/pthreads/ptthread.c
pr/tests/Makefile
pr/tests/Makefile.in
pr/tests/accept.c
pr/tests/acceptread.c
pr/tests/addrstr.c
pr/tests/affinity.c
pr/tests/cltsrv.c
pr/tests/gethost.c
pr/tests/ipv6.c
pr/tests/lltest.c
pr/tests/makedir.c
pr/tests/mbcs.c
pr/tests/nonblock.c
pr/tests/ntioto.c
pr/tests/ntoh.c
pr/tests/op_excl.c
pr/tests/openfile.c
pr/tests/poll_nm.c
pr/tests/provider.c
pr/tests/runtests.ksh
pr/tests/sema.c
pr/tests/semaping.c
pr/tests/semapong.c
pr/tests/server_test.c
pr/tests/servr_kk.c
pr/tests/servr_ku.c
pr/tests/servr_uk.c
pr/tests/servr_uu.c
pr/tests/socket.c
pr/tests/sockopt.c
pr/tests/thrpool_client.c
pr/tests/thrpool_server.c
pr/tests/thruput.c
pr/tests/tmoacc.c
pr/tests/tmocon.c
pr/tests/vercheck.c
pr/tests/version.c
--- a/Makefile
+++ b/Makefile
@@ -96,10 +96,10 @@ endif
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
 	cd $(OBJDIR_NAME); \
 	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdbinary.jar; \
 	cd include; \
 	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
 
-depend: clean
+depend:
 	@echo "NSPR20 has no dependencies.  Skipped."
--- a/Makefile.in
+++ b/Makefile.in
@@ -101,10 +101,10 @@ endif
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/imports.df; \
 	cd $(OBJDIR_NAME); \
 	cp -f mdbinary.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdbinary.jar; \
 	cd include; \
 	cp -f mdheader.jar $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME); \
 	chmod 664 $(MDIST)/$(MOD_NAME)/$(BUILD_NUMBER)/$(OBJDIR_NAME)/mdheader.jar
 
-depend: clean
+depend:
 	@echo "NSPR20 has no dependencies.  Skipped."
--- a/config/Linux.mk
+++ b/config/Linux.mk
@@ -42,16 +42,18 @@ ifeq ($(CLASSIC_NSPR),1)
 IMPL_STRATEGY		= _EMU
 DEFINES			+= -D_PR_LOCAL_THREADS_ONLY
 else
 USE_PTHREADS		= 1
 IMPL_STRATEGY		= _PTH
 DEFINES			+= -D_REENTRANT
 endif
 
+USE_IPV6 = 1
+
 ifeq (86,$(findstring 86,$(OS_TEST)))
 CPU_ARCH		:= x86
 else
 ifeq (,$(filter-out armv4l sa110,$(OS_TEST)))
 CPU_ARCH		:= arm
 else
 CPU_ARCH		:= $(OS_TEST)
 endif
--- a/config/module.df
+++ b/config/module.df
@@ -15,9 +15,9 @@
 # Reserved.
 #
 
 # Module description file
 #
 # A module is also called a component or a subsystem.
 
 MOD_NAME = nspr20
-MOD_VERSION = 3
+MOD_VERSION = 4
new file mode 100644
--- /dev/null
+++ b/config/prdepend.h
@@ -0,0 +1,26 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+/*
+ * A dummy header file that is a dependency for all the object files.
+ * Used to force a full recompilation of NSPR in Mozilla's Tinderbox
+ * depend builds.  See comments in rules.mk.
+ */
+
+#error "Do not include this header file."
+
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -57,22 +57,24 @@ srcdir=.
 endif
 
 ifndef NSPR_CONFIG_MK
 include $(topsrcdir)/config/config.mk
 endif
 
 ifdef USE_AUTOCONF
 ifdef INTERNAL_TOOLS
+ifdef CROSS_COMPILE
 CC=$(HOST_CC)
 CCC=$(HOST_CXX)
 CFLAGS=$(HOST_CFLAGS)
 CXXFLAGS=$(HOST_CXXFLAGS)
 endif
 endif
+endif
 
 #
 # This makefile contains rules for building the following kinds of
 # libraries:
 # - LIBRARY: a static (archival) library
 # - SHARED_LIBRARY: a shared (dynamic link) library
 # - IMPORT_LIBRARY: an import library, used only on Windows and OS/2
 #
@@ -403,16 +405,39 @@ endif
 	$(AS) -o $@ $(ASFLAGS) -c $<
 
 %.i: %.c
 	$(CC) -C -E $(CFLAGS) $< > $*.i
 
 %: %.pl
 	rm -f $@; cp $< $@; chmod +x $@
 
+#
+# HACK ALERT
+#
+# The only purpose of this rule is to pass Mozilla's Tinderbox depend
+# builds (http://tinderbox.mozilla.org/showbuilds.cgi).  Mozilla's
+# Tinderbox builds NSPR continuously as part of the Mozilla client.
+# Because NSPR's make depend is not implemented, whenever we change
+# an NSPR header file, the depend build does not recompile the NSPR
+# files that depend on the header.
+#
+# This rule makes all the objects depend on a dummy header file.
+# Touch this dummy header file to force the depend build to recompile
+# everything.
+#
+# This rule should be removed when make depend is implemented.
+#
+
+DUMMY_DEPEND_H = $(topsrcdir)/config/prdepend.h
+
+$(filter $(OBJDIR)/%.$(OBJ_SUFFIX),$(OBJS)): $(OBJDIR)/%.$(OBJ_SUFFIX): $(DUMMY_DEPEND_H)
+
+# END OF HACK
+
 ################################################################################
 # Special gmake rules.
 ################################################################################
 
 #
 # Re-define the list of default suffixes, so gmake won't have to churn through
 # hundreds of built-in suffix rules for stuff we don't need.
 #
--- a/configure
+++ b/configure
@@ -688,17 +688,17 @@ echo "configure:674: checking cached sys
 
 
 
 cat >> confdefs.h <<\EOF
 #define USE_AUTOCONF 1
 EOF
 
 
-NSPR_VERSION=3
+NSPR_VERSION=4
 NSPR_MODNAME=nspr20
 _HAVE_PTHREADS=
 USE_PTHREADS=
 USE_USER_PTHREADS=
 USE_NSPR_THREADS=
 USE_N32=
 USE_64=
 USE_CPLUS=
@@ -2780,16 +2780,20 @@ EOF
     cat >> confdefs.h <<\EOF
 #define _BSD_SOURCE 1
 EOF
 
     cat >> confdefs.h <<\EOF
 #define _SVID_SOURCE 1
 EOF
 
+    cat >> confdefs.h <<\EOF
+#define LINUX 1
+EOF
+
     CFLAGS="$CFLAGS -pipe -ansi"
     CXXFLAGS="$CXXFLAGS -pipe -ansi"
     MDCPUCFG_H=_linux.cfg
     PR_MD_CSRCS=linux.c
     MKSHLIB='$(LD) $(DSO_LDOPTS) -soname $(notdir $@) -o $@'
     DSO_CFLAGS=-fPIC
     DSO_LDOPTS=-shared
     case "${target_cpu}" in
@@ -3019,72 +3023,72 @@ esac
 if test "$enable_shared" = no; then
     MKSHLIB=
 fi
 
 
 
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:3028: checking how to run the C preprocessor" >&5
+echo "configure:3032: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
 if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     # This must be in double quotes, not single quotes, because CPP may get
   # substituted into the Makefile and "${CC-cc}" will confuse make.
   CPP="${CC-cc} -E"
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 3043 "configure"
+#line 3047 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3049: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3053: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 3060 "configure"
+#line 3064 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3066: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3070: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 3077 "configure"
+#line 3081 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3083: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3087: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
 else
   echo "$ac_err" >&5
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
@@ -3100,23 +3104,23 @@ fi
   CPP="$ac_cv_prog_CPP"
 else
   ac_cv_prog_CPP="$CPP"
 fi
 echo "$ac_t""$CPP" 1>&6
 
 if test $ac_cv_prog_gcc = yes; then
     echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
-echo "configure:3109: checking whether ${CC-cc} needs -traditional" >&5
+echo "configure:3113: checking whether ${CC-cc} needs -traditional" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
     ac_pattern="Autoconf.*'x'"
   cat > conftest.$ac_ext <<EOF
-#line 3115 "configure"
+#line 3119 "configure"
 #include "confdefs.h"
 #include <sgtty.h>
 Autoconf TIOCGETP
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "$ac_pattern" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=yes
@@ -3124,17 +3128,17 @@ else
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=no
 fi
 rm -f conftest*
 
 
   if test $ac_cv_prog_gcc_traditional = no; then
     cat > conftest.$ac_ext <<EOF
-#line 3133 "configure"
+#line 3137 "configure"
 #include "confdefs.h"
 #include <termio.h>
 Autoconf TCGETA
 EOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
   egrep "$ac_pattern" >/dev/null 2>&1; then
   rm -rf conftest*
   ac_cv_prog_gcc_traditional=yes
@@ -3148,22 +3152,22 @@ echo "$ac_t""$ac_cv_prog_gcc_traditional
   if test $ac_cv_prog_gcc_traditional = yes; then
     CC="$CC -traditional"
   fi
 fi
 
 for ac_func in lchown strerror
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3157: checking for $ac_func" >&5
+echo "configure:3161: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3162 "configure"
+#line 3166 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char $ac_func();
@@ -3176,17 +3180,17 @@ int main() {
 #if defined (__stub_$ac_func) || defined (__stub___$ac_func)
 choke me
 #else
 $ac_func();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3185: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3189: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=no"
 fi
@@ -3204,36 +3208,36 @@ else
   echo "$ac_t""no" 1>&6
 fi
 done
 
 
 
 
 echo $ac_n "checking for pthread_attr_init in -lpthread""... $ac_c" 1>&6
-echo "configure:3213: checking for pthread_attr_init in -lpthread" >&5
+echo "configure:3217: checking for pthread_attr_init in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3221 "configure"
+#line 3225 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3232: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3242,36 +3246,36 @@ LIBS="$ac_save_LIBS"
 
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lpthread"
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_attr_init in -lc_r""... $ac_c" 1>&6
-echo "configure:3251: checking for pthread_attr_init in -lc_r" >&5
+echo "configure:3255: checking for pthread_attr_init in -lc_r" >&5
 ac_lib_var=`echo c_r'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lc_r  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3259 "configure"
+#line 3263 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3270: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3280,36 +3284,36 @@ LIBS="$ac_save_LIBS"
 
 fi
 if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   _HAVE_PTHREADS=1 _PTHREAD_LDFLAGS="-lc_r"
 else
   echo "$ac_t""no" 1>&6
 echo $ac_n "checking for pthread_attr_init in -lc""... $ac_c" 1>&6
-echo "configure:3289: checking for pthread_attr_init in -lc" >&5
+echo "configure:3293: checking for pthread_attr_init in -lc" >&5
 ac_lib_var=`echo c'_'pthread_attr_init | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lc  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3297 "configure"
+#line 3301 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_attr_init();
 
 int main() {
 pthread_attr_init()
 ; return 0; }
 EOF
-if { (eval echo configure:3308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3312: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3426,17 +3430,17 @@ if test "${enable_ipv6+set}" = set; then
       fi
 fi
 
 
 if test -n "$USE_PTHREADS"; then
       rm -f conftest*
    ac_cv_have_dash_pthread=no
    echo $ac_n "checking whether ${CC-cc} accepts -pthread""... $ac_c" 1>&6
-echo "configure:3435: checking whether ${CC-cc} accepts -pthread" >&5
+echo "configure:3439: checking whether ${CC-cc} accepts -pthread" >&5
    echo 'int main() { return 0; }' | cat > conftest.c
    ${CC-cc} -pthread -o conftest conftest.c > conftest.out 2>&1
    if test $? -eq 0; then
 	if test -z "`egrep -i '(unrecognize|unknown)' conftest.out | grep pthread`" && test -z "`egrep -i '(error|incorrect)' conftest.out`" ; then
 	    ac_cv_have_dash_pthread=yes
 	    CFLAGS="$CFLAGS -pthread"
 	    CXXFLAGS="$CXXFLAGS -pthread"
 	fi
@@ -3496,22 +3500,22 @@ EOF
 	    cat >> confdefs.h <<\EOF
 #define _REENTRANT 1
 EOF
 
 	    ;;
     esac
 
     echo $ac_n "checking for pthread_create""... $ac_c" 1>&6
-echo "configure:3505: checking for pthread_create" >&5
+echo "configure:3509: checking for pthread_create" >&5
 if eval "test \"`echo '$''{'ac_cv_func_pthread_create'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3510 "configure"
+#line 3514 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char pthread_create(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_create();
@@ -3524,17 +3528,17 @@ int main() {
 #if defined (__stub_pthread_create) || defined (__stub___pthread_create)
 choke me
 #else
 pthread_create();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3533: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3537: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_pthread_create=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_pthread_create=no"
 fi
@@ -3543,36 +3547,36 @@ fi
 
 if eval "test \"`echo '$ac_cv_func_'pthread_create`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
 else
   echo "$ac_t""no" 1>&6
 
        echo $ac_n "checking for pthread_create in -lpthread""... $ac_c" 1>&6
-echo "configure:3552: checking for pthread_create in -lpthread" >&5
+echo "configure:3556: checking for pthread_create in -lpthread" >&5
 ac_lib_var=`echo pthread'_'pthread_create | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-lpthread  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3560 "configure"
+#line 3564 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char pthread_create();
 
 int main() {
 pthread_create()
 ; return 0; }
 EOF
-if { (eval echo configure:3571: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
@@ -3661,22 +3665,22 @@ EOF
                 PR_MD_ASFILES="$PR_MD_ASFILES os_SunOS_32.s"
             fi
         fi
     fi
     ;;
 esac
 
 echo $ac_n "checking for dlopen""... $ac_c" 1>&6
-echo "configure:3670: checking for dlopen" >&5
+echo "configure:3674: checking for dlopen" >&5
 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3675 "configure"
+#line 3679 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char dlopen(); below.  */
 #include <assert.h>
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char dlopen();
@@ -3689,17 +3693,17 @@ int main() {
 #if defined (__stub_dlopen) || defined (__stub___dlopen)
 choke me
 #else
 dlopen();
 #endif
 
 ; return 0; }
 EOF
-if { (eval echo configure:3698: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_dlopen=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_func_dlopen=no"
 fi
@@ -3708,36 +3712,36 @@ fi
 
 if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then
   echo "$ac_t""yes" 1>&6
   :
 else
   echo "$ac_t""no" 1>&6
 
     echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
-echo "configure:3717: checking for dlopen in -ldl" >&5
+echo "configure:3721: checking for dlopen in -ldl" >&5
 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_save_LIBS="$LIBS"
 LIBS="-ldl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3725 "configure"
+#line 3729 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
     builtin and then its argument prototype would still apply.  */
 char dlopen();
 
 int main() {
 dlopen()
 ; return 0; }
 EOF
-if { (eval echo configure:3736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
   echo "configure: failed program was:" >&5
   cat conftest.$ac_ext >&5
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=no"
 fi
--- a/configure.in
+++ b/configure.in
@@ -35,17 +35,17 @@ AC_VALIDATE_CACHED_SYSTEM_TUPLE
 AC_PREFIX_DEFAULT(\${MOD_DEPTH}/dist)
 
 dnl Set this define to make fixes w/o breaking anything else.
 AC_DEFINE(USE_AUTOCONF)
 
 dnl ========================================================
 dnl = Defaults
 dnl ========================================================
-NSPR_VERSION=3
+NSPR_VERSION=4
 NSPR_MODNAME=nspr20
 _HAVE_PTHREADS=
 USE_PTHREADS=
 USE_USER_PTHREADS=
 USE_NSPR_THREADS=
 USE_N32=
 USE_64=
 USE_CPLUS=
@@ -550,16 +550,17 @@ case "$target" in
     esac
     ;;
 
 *-linux*)
     AC_DEFINE(XP_UNIX)
     AC_DEFINE(_POSIX_SOURCE)
     AC_DEFINE(_BSD_SOURCE)
     AC_DEFINE(_SVID_SOURCE)
+    AC_DEFINE(LINUX)
     CFLAGS="$CFLAGS -pipe -ansi"
     CXXFLAGS="$CXXFLAGS -pipe -ansi"
     MDCPUCFG_H=_linux.cfg
     PR_MD_CSRCS=linux.c
     MKSHLIB='$(LD) $(DSO_LDOPTS) -soname $(notdir $@) -o $@'
     DSO_CFLAGS=-fPIC
     DSO_LDOPTS=-shared
     case "${target_cpu}" in
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -20,17 +20,13 @@
 MOD_DEPTH = ..
 
 export NSPR20=1
 
 include $(MOD_DEPTH)/config/config.mk
 
 DIRS = ds libc
 
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
 include $(MOD_DEPTH)/config/rules.mk
 
 export:: $(TARGETS)
 
 install:: export
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -25,17 +25,13 @@ VPATH		= @srcdir@
 include $(MOD_DEPTH)/config/autoconf.mk
 
 export NSPR20=1
 
 include $(topsrcdir)/config/config.mk
 
 DIRS = ds libc
 
-ifneq (,$(filter-out Rhapsody WIN16 NEWS-OS,$(OS_TARGET)))
-DIRS += prstreams
-endif
-
 include $(topsrcdir)/config/rules.mk
 
 export:: $(TARGETS)
 
 install:: export
--- a/lib/ds/MANIFEST
+++ b/lib/ds/MANIFEST
@@ -1,8 +1,7 @@
 #
 # This is a list of local files which get copied to the mozilla:dist directory
 #
 
 plarenas.h
 plarena.h
-plevent.h
 plhash.h
--- a/lib/ds/Makefile
+++ b/lib/ds/Makefile
@@ -27,25 +27,23 @@ ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include
 
 CSRCS = \
 	plarena.c \
-	plevent.c \
 	plhash.c \
 	plvrsion.c \
 	$(NULL)
 
 HEADERS = \
 	plarenas.h \
 	plarena.h \
-	plevent.h \
 	plhash.h \
 	$(NULL)
 
 ifeq ($(OS_ARCH), WINNT)
 ifeq ($(OS_TARGET), WIN16)
 # OS_CFLAGS = $(OS_EXE_CFLAGS)
 EXTRA_LIBS = $(DIST)/lib/nspr$(MOD_VERSION).$(LIB_SUFFIX)
 else
--- a/lib/ds/Makefile.in
+++ b/lib/ds/Makefile.in
@@ -34,25 +34,23 @@ OPTIMIZER =
 endif
 endif
 endif #!USE_AUTOCONF
 
 INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include
 
 CSRCS = \
 	plarena.c \
-	plevent.c \
 	plhash.c \
 	plvrsion.c \
 	$(NULL)
 
 HEADERS = \
 	plarenas.h \
 	plarena.h \
-	plevent.h \
 	plhash.h \
 	$(NULL)
 
 HEADERS := $(addprefix $(srcdir)/, $(HEADERS))
 
 ifndef USE_AUTOCONF
 ifeq ($(OS_ARCH), WINNT)
 ifeq (,$(filter-out WIN16 OS2,$(OS_TARGET)))
--- a/lib/ds/plds.rc
+++ b/lib/ds/plds.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "plds"
 #define MY_FILEDESCRIPTION "PLDS Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
deleted file mode 100644
--- a/lib/ds/plevent.c
+++ /dev/null
@@ -1,1087 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL.  You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- * 
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- * 
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
- * Reserved.
- */
-
-#if defined(_WIN32) || defined(WIN16)
-#include <windows.h>
-#endif
-
-#if defined(XP_OS2)
-#define INCL_WIN
-#include <os2.h>
-#define DefWindowProc WinDefWindowProc
-typedef MPARAM WPARAM,LPARAM;
-#endif /* XP_OS2 */
-
-#include "nspr.h"
-#include "plevent.h"
-
-#if !defined(WIN32)
-#include <errno.h>
-#include <stddef.h>
-#if !defined(XP_OS2)
-#include <unistd.h>
-#endif /* !XP_OS2 */
-#endif /* !Win32 */
-
-#if defined(XP_UNIX)
-/* for fcntl */
-#include <sys/types.h>
-#include <fcntl.h>
-#endif
-
-#if defined(XP_BEOS)
-#include <kernel/OS.h>
-#endif
-
-#if defined(XP_MAC)
-#include <AppleEvents.h>
-#include "pprthred.h"
-#else
-#include "private/pprthred.h"
-#endif /* XP_MAC */
-
-#if defined(VMS)
-/*
-** On OpenVMS, XtAppAddInput doesn't want a regular fd, instead it 
-** wants an event flag. So, we don't create and use a pipe for 
-** notification of when an event queue has something ready, instead
-** we use an event flag. Shouldn't be a problem if we only have
-** a few event queues.
-*/
-#include <lib$routines.h>
-#include <starlet.h>
-#include <stsdef.h>
-#endif /* VMS */
-
-
-static PRLogModuleInfo *event_lm = NULL;
-
-/*******************************************************************************
- * Private Stuff
- ******************************************************************************/
-
-/*
-** EventQueueType -- Defines notification type for an event queue
-**
-*/
-typedef enum 
-{
-    EventQueueIsNative = 1,
-    EventQueueIsMonitored = 2
-} EventQueueType;
-
-
-struct PLEventQueue {
-    char*        name;
-    PRCList      queue;
-    PRMonitor*   monitor;
-    PRThread*    handlerThread;
-    EventQueueType type;
-    PRBool       processingEvents;
-#if defined(VMS)
-    int		 efn;
-    int		 notifyCount;
-#elif defined(XP_UNIX)
-    PRInt32      eventPipe[2];
-	int          notifyCount;
-#elif defined(_WIN32) || defined(WIN16)
-    HWND         eventReceiverWindow;
-#elif defined(XP_OS2)
-    HWND         eventReceiverWindow;
-#elif defined(XP_BEOS)
-    port_id      eventport;
-#endif
-};
-
-#define PR_EVENT_PTR(_qp) \
-    ((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);
-static void        _md_CreateEventQueue( PLEventQueue *eventQueue );
-static PRInt32     _pl_GetEventCount(PLEventQueue* self);
-
-
-#if defined(_WIN32) || defined(WIN16) || defined(XP_OS2)
-#if defined(XP_OS2)
-ULONG _pr_PostEventMsgId;
-static char *_pr_eventWindowClass = "NSPR:EventWindow";
-#else
-UINT _pr_PostEventMsgId;
-static char *_pr_eventWindowClass = "NSPR:EventWindow";
-#endif /* OS2 */
-#endif /* Win32, Win16, OS2 */
-
-/*******************************************************************************
- * Event Queue Operations
- ******************************************************************************/
-
-/*
-** _pl_CreateEventQueue() -- Create the event queue
-**
-**
-*/
-static PLEventQueue *
-    _pl_CreateEventQueue(
-        char *name,
-        PRThread *handlerThread,
-        EventQueueType  qtype
-)
-{
-    PRStatus err;
-    PLEventQueue* self = NULL;
-    PRMonitor* mon = NULL;
-
-    if (event_lm == NULL)
-        event_lm = PR_NewLogModule("event");
-
-    self = PR_NEWZAP(PLEventQueue);
-    if (self == NULL) return NULL;
-
-    mon = PR_NewNamedMonitor(name);
-    if (mon == NULL) goto error;
-
-    self->name = name;
-    self->monitor = mon;
-    self->handlerThread = handlerThread;
-    self->processingEvents = PR_FALSE;
-    self->type = qtype;
-    PR_INIT_CLIST(&self->queue);
-    if ( qtype == EventQueueIsNative )
-    {
-        err = _pl_SetupNativeNotifier(self);
-        if (err) goto error;
-    }
-    _md_CreateEventQueue( self );
-    return self;
-
-  error:
-    if (mon != NULL)
-    PR_DestroyMonitor(mon);
-    PR_DELETE(self);
-    return NULL;
-} /* end _pl_CreateEventQueue() */
-
-
-PR_IMPLEMENT(PLEventQueue*)
-PL_CreateEventQueue(char* name, PRThread* handlerThread)
-{
-    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
-}
-
-PR_EXTERN(PLEventQueue *) 
-    PL_CreateNativeEventQueue(
-        char *name, 
-        PRThread *handlerThread
-    )
-{
-    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsNative ));
-} /* --- end PL_CreateNativeEventQueue() --- */
-
-PR_EXTERN(PLEventQueue *) 
-    PL_CreateMonitoredEventQueue(
-        char *name,
-        PRThread *handlerThread
-    )
-{
-    return( _pl_CreateEventQueue( name, handlerThread, EventQueueIsMonitored ));
-} /* --- end PL_CreateMonitoredEventQueue() --- */
-
-
-
-PR_IMPLEMENT(PRMonitor*)
-PL_GetEventQueueMonitor(PLEventQueue* self)
-{
-    return self->monitor;
-}
-
-static void PR_CALLBACK
-_pl_destroyEvent(PLEvent* event, void* data, PLEventQueue* queue)
-{
-#ifdef XP_MAC
-#pragma unused (data, queue)
-#endif
-    PL_DequeueEvent(event, queue);
-    PL_DestroyEvent(event);
-}
-
-PR_IMPLEMENT(void)
-PL_DestroyEventQueue(PLEventQueue* self)
-{
-    PR_EnterMonitor(self->monitor);
-
-    /* destroy undelivered events */
-    PL_MapEvents(self, _pl_destroyEvent, NULL);
-
-    if ( self->type == EventQueueIsNative )
-        _pl_CleanupNativeNotifier(self);
-
-    /* destroying the monitor also destroys the name */
-    PR_ExitMonitor(self->monitor);
-    PR_DestroyMonitor(self->monitor);
-    PR_DELETE(self);
-
-}
-
-PR_IMPLEMENT(PRStatus)
-PL_PostEvent(PLEventQueue* self, PLEvent* event)
-{
-    PRStatus err = PR_SUCCESS;
-    PRMonitor* mon;
-
-    if (self == NULL)
-    return PR_FAILURE;
-
-    mon = self->monitor;
-    PR_EnterMonitor(mon);
-
-    /* insert event into thread's event queue: */
-    if (event != NULL) {
-    PR_APPEND_LINK(&event->link, &self->queue);
-    }
-
-    /* notify even if event is NULL */
-    if ( self->type == EventQueueIsNative )
-        err = _pl_NativeNotify(self);
-
-    /*
-     * This may fall on deaf ears if we're really notifying the native 
-     * thread, and no one has called PL_WaitForEvent (or PL_EventLoop):
-     */
-    err = PR_Notify(mon);
-    PR_ExitMonitor(mon);
-    return err;
-}
-
-PR_IMPLEMENT(void*)
-PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event)
-{
-    void* result;
-
-    if (self == NULL)
-    return NULL;
-
-    PR_ASSERT(event != NULL);
-    PR_CEnterMonitor(event);
-
-    if (PR_CurrentThread() == self->handlerThread) {
-	/* Handle the case where the thread requesting the event handling
-	   is also the thread that's supposed to do the handling. */
-	result = event->handler(event);
-    }
-    else {
-	int i, entryCount = PR_GetMonitorEntryCount(self->monitor);
-
-	event->synchronousResult = (void*)PR_TRUE;
-	PL_PostEvent(self, event);
-	/* We need to temporarily give up our event queue monitor if
-	   we're holding it, otherwise, the thread we're going to wait
-	   for notification from won't be able to enter it to process
-	   the event. */
-	if (entryCount) {
-	    for (i = 0; i < entryCount; i++)
-		PR_ExitMonitor(self->monitor);
-	}
-	PR_CWait(event, PR_INTERVAL_NO_TIMEOUT);	/* wait for event to be handled or destroyed */
-	if (entryCount) {
-	    for (i = 0; i < entryCount; i++)
-		PR_EnterMonitor(self->monitor);
-	}
-    	result = event->synchronousResult;
-	event->synchronousResult = NULL;
-    }
-
-    PR_CExitMonitor(event);
-
-    /* For synchronous events, they're destroyed here on the caller's
-       thread before the result is returned. See PL_HandleEvent. */
-    PL_DestroyEvent(event);
-
-    return result;
-}
-
-PR_IMPLEMENT(PLEvent*)
-PL_GetEvent(PLEventQueue* self)
-{
-    PLEvent* event = NULL;
-    PRStatus err = PR_SUCCESS;
-
-    if (self == NULL)
-    return NULL;
-
-    PR_EnterMonitor(self->monitor);
-
-    if (!PR_CLIST_IS_EMPTY(&self->queue)) {
-      if ( self->type == EventQueueIsNative )
-        err = _pl_AcknowledgeNativeNotify(self);
-
-      if (err) goto done;
-
-      /* then grab the event and return it: */
-      event = PR_EVENT_PTR(self->queue.next);
-      PR_REMOVE_AND_INIT_LINK(&event->link);
-    }
-
-  done:
-    PR_ExitMonitor(self->monitor);
-    return event;
-}
-
-PR_IMPLEMENT(PRBool)
-PL_EventAvailable(PLEventQueue* self)
-{
-    PRBool result = PR_FALSE;
-
-    if (self == NULL)
-    return PR_FALSE;
-
-    PR_EnterMonitor(self->monitor);
-
-    if (!PR_CLIST_IS_EMPTY(&self->queue)) 
-    result = PR_TRUE;
-
-    PR_ExitMonitor(self->monitor);
-    return result;
-}
-
-PR_IMPLEMENT(void)
-PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data)
-{
-    PRCList* qp;
-
-    if (self == NULL)
-    return;
-
-    PR_EnterMonitor(self->monitor);
-    qp = self->queue.next;
-    while (qp != &self->queue) {
-    PLEvent* event = PR_EVENT_PTR(qp);
-    qp = qp->next;
-    (*fun)(event, data, self);
-    }
-    PR_ExitMonitor(self->monitor);
-}
-
-static void PR_CALLBACK
-_pl_DestroyEventForOwner(PLEvent* event, void* owner, PLEventQueue* queue)
-{
-    PR_ASSERT(PR_GetMonitorEntryCount(queue->monitor) > 0);
-    if (event->owner == owner) {
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("$$$ \tdestroying event %0x for owner %0x", event, owner));
-    PL_DequeueEvent(event, queue);
-    if (event->synchronousResult == (void*)PR_TRUE) {
-        PR_CEnterMonitor(event);
-        event->synchronousResult = NULL;
-        PR_CNotify(event);
-        PR_CExitMonitor(event);
-    }
-    else {
-        PL_DestroyEvent(event);
-    }
-    }
-    else {
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("$$$ \tskipping event %0x for owner %0x", event, owner));
-    }
-}
-
-PR_IMPLEMENT(void)
-PL_RevokeEvents(PLEventQueue* self, void* owner)
-{
-    if (self == NULL)
-    return;
-
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-         ("$$$ revoking events for owner %0x", owner));
-
-    /*
-    ** First we enter the monitor so that no one else can post any events
-    ** to the queue:
-    */
-    PR_EnterMonitor(self->monitor);
-    PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ owner %0x, entered monitor", owner));
-
-    /*
-    ** Discard any pending events for this owner:
-    */
-    PL_MapEvents(self, _pl_DestroyEventForOwner, owner);
-
-#ifdef DEBUG
-    {
-	PRCList* qp = self->queue.next;
-	while (qp != &self->queue) {
-	    PLEvent* event = PR_EVENT_PTR(qp);
-	    qp = qp->next;
-	    PR_ASSERT(event->owner != owner);
-	}
-    }
-#endif /* DEBUG */
-
-    PR_ExitMonitor(self->monitor);
-
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("$$$ revoking events for owner %0x", owner));
-}
-
-static PRInt32
-_pl_GetEventCount(PLEventQueue* self)
-{
-    PRCList* node;
-    PRInt32  count = 0;
-
-    PR_EnterMonitor(self->monitor);
-    node = PR_LIST_HEAD(&self->queue);
-    while (node != &self->queue) {
-        count++;
-        node = PR_NEXT_LINK(node);
-    }
-    PR_ExitMonitor(self->monitor);
-
-    return count;
-}
-
-PR_IMPLEMENT(void)
-PL_ProcessPendingEvents(PLEventQueue* self)
-{
-    PRInt32 count;
-    
-    if (self == NULL)
-    return;
-
-  if (PR_FALSE != self->processingEvents) return;
-
-    self->processingEvents = PR_TRUE;
-
-    /* Only process the events that are already in the queue, and
-     * not any new events that get added. Do this by counting the
-     * number of events currently in the queue
-     */
-    count = _pl_GetEventCount(self);
-    while (count-- > 0) {
-    PLEvent* event = PL_GetEvent(self);
-        if (event == NULL) break;
-
-    PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
-    PL_HandleEvent(event);
-    PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
-    }
-    self->processingEvents = PR_FALSE;
-}
-
-/*******************************************************************************
- * Event Operations
- ******************************************************************************/
-
-PR_IMPLEMENT(void)
-PL_InitEvent(PLEvent* self, void* owner,
-         PLHandleEventProc handler,
-         PLDestroyEventProc destructor)
-{
-    PR_INIT_CLIST(&self->link);
-    self->handler = handler;
-    self->destructor = destructor;
-    self->owner = owner;
-    self->synchronousResult = NULL;
-}
-
-PR_IMPLEMENT(void*)
-PL_GetEventOwner(PLEvent* self)
-{
-    return self->owner;
-}
-
-PR_IMPLEMENT(void)
-PL_HandleEvent(PLEvent* self)
-{
-    void* result;
-
-    if (self == NULL)
-        return;
-
-    /* This event better not be on an event queue anymore. */
-    PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));
-
-    result = (*self->handler)(self);
-    if (NULL != self->synchronousResult) {
-    PR_CEnterMonitor(self);
-    self->synchronousResult = result;
-    PR_CNotify(self);    /* wake up the guy waiting for the result */
-    PR_CExitMonitor(self);
-    }
-    else {
-    /* For asynchronous events, they're destroyed by the event-handler
-       thread. See PR_PostSynchronousEvent. */
-    PL_DestroyEvent(self);
-    }
-}
-
-PR_IMPLEMENT(void)
-PL_DestroyEvent(PLEvent* self)
-{
-    if (self == NULL)
-    return;
-
-    /* This event better not be on an event queue anymore. */
-    PR_ASSERT(PR_CLIST_IS_EMPTY(&self->link));
-
-    (*self->destructor)(self);
-}
-
-PR_IMPLEMENT(void)
-PL_DequeueEvent(PLEvent* self, PLEventQueue* queue)
-{
-#ifdef XP_MAC
-#pragma unused (queue)
-#endif
-    if (self == NULL)
-    return;
-
-    /* Only the owner is allowed to dequeue events because once the 
-       client has put it in the queue, they have no idea whether it's 
-       been processed and destroyed or not. */
-/*    PR_ASSERT(queue->handlerThread == PR_CurrentThread());*/
-
-    PR_EnterMonitor(queue->monitor);
-
-    PR_ASSERT(!PR_CLIST_IS_EMPTY(&self->link));
-    PR_REMOVE_AND_INIT_LINK(&self->link);
-
-    PR_ExitMonitor(queue->monitor);
-}
-
-/*******************************************************************************
- * Pure Event Queues
- *
- * For when you're only processing PLEvents and there is no native
- * select, thread messages, or AppleEvents.
- ******************************************************************************/
-
-PR_IMPLEMENT(PLEvent*)
-PL_WaitForEvent(PLEventQueue* self)
-{
-    PLEvent* event;
-    PRMonitor* mon;
-
-    if (self == NULL)
-    return NULL;
-
-    mon = self->monitor;
-    PR_EnterMonitor(mon);
-
-    while ((event = PL_GetEvent(self)) == NULL) {
-        PRStatus err;
-        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ waiting for event"));
-        err = PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
-        if ((err == PR_FAILURE)
-            && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) break;
-    }
-
-    PR_ExitMonitor(mon);
-    return event;
-}
-
-PR_IMPLEMENT(void)
-PL_EventLoop(PLEventQueue* self)
-{
-    if (self == NULL)
-    return;
-
-    while (PR_TRUE) {
-    PLEvent* event = PL_WaitForEvent(self);
-    if (event == NULL) {
-        /* This can only happen if the current thread is interrupted */
-        return;
-    }
-
-        PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ processing event"));
-    PL_HandleEvent(event);
-    PR_LOG(event_lm, PR_LOG_DEBUG, ("$$$ done processing event"));
-    }
-}
-
-/*******************************************************************************
- * Native Event Queues
- *
- * For when you need to call select, or WaitNextEvent, and yet also want
- * to handle PLEvents.
- ******************************************************************************/
-
-static PRStatus
-_pl_SetupNativeNotifier(PLEventQueue* self)
-{
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
-#if defined(VMS)
-    {
-        unsigned int status;
-        status = LIB$GET_EF(&self->efn);
-        if (!$VMS_STATUS_SUCCESS(status))
-            return PR_FAILURE;
-        PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("$$$ Allocated event flag %d", self->efn));
-        return PR_SUCCESS;
-    }
-#elif defined(XP_UNIX)
-    int err;
-    int flags;
-
-    err = pipe(self->eventPipe);
-    if (err != 0) {
-        return PR_FAILURE;
-    }
-
-    /* make the pipe nonblocking */
-    flags = fcntl(self->eventPipe[0], F_GETFL, 0);
-    if (flags == -1) {
-        goto failed;
-    }
-    err = fcntl(self->eventPipe[0], F_SETFL, flags | O_NONBLOCK);
-    if (err == -1) {
-        goto failed;
-    }
-    flags = fcntl(self->eventPipe[1], F_GETFL, 0);
-    if (flags == -1) {
-        goto failed;
-    }
-    err = fcntl(self->eventPipe[1], F_SETFL, flags | O_NONBLOCK);
-    if (err == -1) {
-        goto failed;
-    }
-    return PR_SUCCESS;
-
-failed:
-    close(self->eventPipe[0]);
-    close(self->eventPipe[1]);
-    return PR_FAILURE;
-#elif defined(XP_BEOS)
-	/* hook up to the nsToolkit queue, however the appshell
-	 * isn't necessairly started, so we might have to create
-	 * the queue ourselves
-	 */
-	char		portname[64];
-	char		semname[64];
-	sprintf(portname, "event%lx", self->handlerThread);
-	sprintf(semname, "sync%lx", self->handlerThread);
-
-	if((self->eventport = find_port(portname)) < 0)
-	{
-		/* create port
-		 */
-		self->eventport = create_port(100, portname);
-
-		/* We don't use the sem, but it has to be there
-		 */
-		create_sem(0, semname);
-	}
-
-    return PR_SUCCESS;
-#else
-    return PR_SUCCESS;
-#endif
-}
-
-static void
-_pl_CleanupNativeNotifier(PLEventQueue* self)
-{
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
-#if defined(VMS)
-    {
-        unsigned int status;
-        PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("$$$ Freeing event flag %d", self->efn));
-        status = LIB$FREE_EF(&self->efn);
-    }
-#elif defined(XP_UNIX)
-    close(self->eventPipe[0]);
-    close(self->eventPipe[1]);
-#endif
-}
-
-#if defined(_WIN32) || defined(WIN16)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-	PostMessage( self->eventReceiverWindow, _pr_PostEventMsgId,
-	    (WPARAM)0, (LPARAM)self);
-    return PR_SUCCESS;
-}/* --- end _pl_NativeNotify() --- */
-#endif
-
-#if defined(XP_OS2)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-    BOOL rc = WinPostMsg( self->eventReceiverWindow, _pr_PostEventMsgId,
-                       0, MPFROMP(self));
-    return (rc == TRUE) ? PR_SUCCESS : PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#endif /* XP_OS2 */
-
-#if defined(VMS)
-/* Just set the event flag */
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-        unsigned int status;
-        PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("_pl_NativeNotify: self=%p notifyCount=%d efn=%d",
-            self, self->notifyCount, self->efn));
-        self->notifyCount++;
-        status = SYS$SETEF(self->efn);
-        if ($VMS_STATUS_SUCCESS(status))
-            return PR_SUCCESS;
-        else
-            return PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#elif defined(XP_UNIX)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-#define NOTIFY_TOKEN    0xFA
-    PRInt32 count;
-    unsigned char buf[] = { NOTIFY_TOKEN };
-
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-           ("_pl_NativeNotify: self=%p notifyCount=%d",
-            self, self->notifyCount));
-    count = write(self->eventPipe[1], buf, 1);
-	if (count == 1) {
-		self->notifyCount++;
-		return PR_SUCCESS;
-	} else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
-		return PR_SUCCESS;
-	} else
-		return PR_FAILURE;
-}/* --- end _pl_NativeNotify() --- */
-#endif /* XP_UNIX */
-
-#if defined(XP_BEOS)
-struct ThreadInterfaceData
-{
-	void	*data;
-	int32	sync;
-};
-
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-	struct ThreadInterfaceData	 id;
-	id.data = self;
-	id.sync = false;
-	write_port(self->eventport, 'natv', &id, sizeof(id));
-
-    return PR_SUCCESS;    /* Is this correct? */
-}
-#endif /* XP_BEOS */
-
-#if defined(XP_MAC)
-static PRStatus
-_pl_NativeNotify(PLEventQueue* self)
-{
-#pragma unused (self)
-    return PR_SUCCESS;    /* XXX can fail? */
-}
-#endif /* XP_MAC */
-
-static PRStatus
-_pl_AcknowledgeNativeNotify(PLEventQueue* self)
-{
-#if defined(VMS)
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-            ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d efn=%d",
-             self, self->notifyCount, self->efn));
-    /*
-    ** If this is the last entry, then clear the event flag. Also make sure
-    ** the flag is cleared on any spurious wakeups.
-    */
-    if (self->notifyCount <= 1)
-        sys$clref(self->efn);
-
-    if (self->notifyCount <= 0)
-        return PR_SUCCESS;
-
-    self->notifyCount--;
-
-    return PR_SUCCESS;
-#elif defined(XP_UNIX)
-
-    PRInt32 count;
-    unsigned char c;
-
-    PR_LOG(event_lm, PR_LOG_DEBUG,
-            ("_pl_AcknowledgeNativeNotify: self=%p notifyCount=%d",
-             self, self->notifyCount));
-	if (self->notifyCount <= 0) return PR_SUCCESS;
-    /* consume the byte NativeNotify put in our pipe: */
-    count = read(self->eventPipe[0], &c, 1);
-	if ((count == 1) && (c == NOTIFY_TOKEN)) {
-		self->notifyCount--;
-		return PR_SUCCESS;
-	} else if ((count == -1) && ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
-		return PR_SUCCESS;
-	} else
-		return PR_FAILURE;
-#else
-
-#if defined(XP_MAC)
-#pragma unused (self)
-#endif
-
-    /* nothing to do on the other platforms */
-    return PR_SUCCESS;
-#endif
-}
-
-PR_IMPLEMENT(PRInt32)
-PL_GetEventQueueSelectFD(PLEventQueue* self)
-{
-    if (self == NULL)
-    return -1;
-
-#if defined(VMS)
-    return -(self->efn);
-#elif defined(XP_UNIX)
-    return self->eventPipe[0];
-#else
-    return -1;    /* other platforms don't handle this (yet) */
-#endif
-}
-
-PR_IMPLEMENT(PRBool)
-PL_IsQueueOnCurrentThread( PLEventQueue *queue )
-{
-    PRThread *me = PR_GetCurrentThread();
-    if ( me == queue->handlerThread )
-        return PR_TRUE;
-    else
-        return PR_FALSE;
-} /* end PL_IsQueueOnCurrentThread() */
-
-#if defined(WIN16) || defined(_WIN32)
-/*
-** Global Instance handle...
-** In Win32 this is the module handle of the DLL.
-**
-*/
-static HINSTANCE _pr_hInstance;
-#endif
-
-#if defined(WIN16)
-/*
-** Function LibMain() is required by Win16
-**
-*/
-int CALLBACK LibMain( HINSTANCE hInst, WORD wDataSeg, 
-                      WORD cbHeapSize, LPSTR lpszCmdLine )
-{
-    _pr_hInstance = hInst;
-    return TRUE;
-}
-#endif /* WIN16 */
-
-#if defined(_WIN32)
-
-/*
-** Initialization routine for the NSPR DLL...
-*/
-
-BOOL WINAPI DllMain (HINSTANCE hDLL, DWORD dwReason, LPVOID lpReserved)
-{
-  switch (dwReason)
-  {
-    case DLL_PROCESS_ATTACH:
-      _pr_hInstance = hDLL;
-      break;
-
-    case DLL_THREAD_ATTACH:
-      break;
-
-    case DLL_THREAD_DETACH:
-      break;
-
-    case DLL_PROCESS_DETACH:
-      _pr_hInstance = NULL;
-      break;
-  }
-
-    return TRUE;
-}
-#endif
-
-
-#if defined(WIN16) || defined(_WIN32) || defined(XP_OS2)
-#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_ProcessPendingEvents(queue);
-#ifdef XP_OS2
-            return MRFROMLONG(TRUE);
-#else
-            return TRUE;
-#endif
-        }
-    return DefWindowProc(hwnd, uMsg, wParam, lParam);
-}
-
-
-static PRBool   isInitialized;
-static PRCallOnceType once;
-static PRLock   *initLock;
-
-/*
-** InitWinEventLib() -- Create the Windows initialization lock
-**
-*/
-static PRStatus InitEventLib( void )
-{
-    PR_ASSERT( initLock == NULL );
-    
-    initLock = PR_NewLock();
-    if ( NULL == initLock )
-        return PR_FAILURE;
-    else
-        return PR_SUCCESS;
-} /* end InitWinEventLib() */
-
-#endif /* Win16, Win32, OS2 */
-
-#if defined(_WIN32) || defined(WIN16)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
-    WNDCLASS wc;
-    
-    /*
-    ** If this is the first call to PL_InitializeEventsLib(),
-    ** make the call to InitWinEventLib() to create the initLock.
-    **
-    ** Then lock the initializer lock to insure that
-    ** we have exclusive control over the initialization sequence.
-    **
-    */
-
-
-    /* Register the windows message for NSPR Event notification */
-    _pr_PostEventMsgId = RegisterWindowMessage("NSPR_PostEvent");
-
-    /* Register the class for the event receiver window */
-    if (!GetClassInfo(_pr_hInstance, _pr_eventWindowClass, &wc)) {
-        wc.style         = 0;
-        wc.lpfnWndProc   = _md_EventReceiverProc;
-        wc.cbClsExtra    = 0;
-        wc.cbWndExtra    = 0;
-        wc.hInstance     = _pr_hInstance;
-        wc.hIcon         = NULL;
-        wc.hCursor       = NULL;
-        wc.hbrBackground = (HBRUSH) NULL;
-        wc.lpszMenuName  = (LPCSTR) NULL;
-        wc.lpszClassName = _pr_eventWindowClass;
-        RegisterClass(&wc);
-        }
-        
-    /* Create the event receiver window */
-    eventQueue->eventReceiverWindow = CreateWindow(_pr_eventWindowClass,
-                                        "NSPR:EventReceiver",
-                                            0, 0, 0, 10, 10,
-                                            NULL, NULL, _pr_hInstance,
-                                            NULL);
-    PR_ASSERT(eventQueue->eventReceiverWindow);
-
-    return;    
-} /* end _md_CreateEventQueue() */
-#endif /* Winxx */
-
-#if defined(XP_OS2)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
-    /* Must have HMQ for this & can't assume we already have appshell */
-    if( FALSE == WinQueryQueueInfo( HMQ_CURRENT, NULL, 0))
-    {
-       HAB hab = WinInitialize( 0);
-       WinCreateMsgQueue( hab, 0);
-    }
-
-    if( !_pr_PostEventMsgId)
-    {
-       WinRegisterClass( 0 /* hab_current */,
-                         _pr_eventWindowClass,
-                         _md_EventReceiverProc,
-                         0, 0);
-
-       _pr_PostEventMsgId = WinAddAtom( WinQuerySystemAtomTable(),
-                                        "NSPR_PostEvent");
-    }
-
-    eventQueue->eventReceiverWindow = WinCreateWindow( HWND_DESKTOP,
-                                                       _pr_eventWindowClass,
-                                                       "", 0,
-                                                       0, 0, 0, 0,
-                                                       HWND_DESKTOP,
-                                                       HWND_TOP,
-                                                       0,
-                                                       NULL,
-                                                       NULL);
-    PR_ASSERT(eventQueue->eventReceiverWindow);
-
-    return;    
-} /* end _md_CreateEventQueue() */
-#endif /* XP_OS2 */
-
-#if defined(XP_UNIX) || defined(XP_MAC) || defined(XP_BEOS)
-/*
-** _md_CreateEventQueue() -- ModelDependent initializer
-*/
-static void _md_CreateEventQueue( PLEventQueue *eventQueue )
-{
-#ifdef XP_MAC 
-#pragma unused(eventQueue) 
-#endif 
-
-    /* there's really nothing special to do here,
-    ** the guts of the unix stuff is in the setupnativenotify
-    ** and related functions.
-    */
-    return;    
-} /* end _md_CreateEventQueue() */
-#endif /* XP_UNIX */
-/* --- end plevent.c --- */
deleted file mode 100644
--- a/lib/ds/plevent.h
+++ /dev/null
@@ -1,497 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL.  You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- * 
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- * 
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
- * Reserved.
- */
-
-/**********************************************************************
-NSPL Events
-
-Defining Events
----------------
-
-Events are essentially structures that represent argument lists for a
-function that will run on another thread. All event structures you
-define must include a PLEvent struct as their first field:
-
-    typedef struct MyEventType {
-        PLEvent	e;
-		// arguments follow...
-        int	x;
-		char*	y;
-    } MyEventType;
-
-It is also essential that you establish a model of ownership for each
-argument passed in an event record, i.e. whether particular arguments
-will be deleted by the event destruction callback, or whether they
-only loaned to the event handler callback, and guaranteed to persist
-until the time at which the handler is called.
-
-Sending Events
---------------
-
-Events are initialized by PL_InitEvent and can be sent via
-PL_PostEvent or PL_PostSynchronousEvent. Events can also have an
-owner. The owner of an event can revoke all the events in a given
-event-queue by calling PL_RevokeEvents. An owner might want
-to do this if, for instance, it is being destroyed, and handling the
-events after the owner's destruction would cause an error (e.g. an
-MWContext).
-
-Since the act of initializing and posting an event must be coordinated
-with it's possible revocation, it is essential that the event-queue's
-monitor be entered surrounding the code that constructs, initializes
-and posts the event:
-
-    void postMyEvent(MyOwner* owner, int x, char* y)
-    {
-		MyEventType* event;
-
-		PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
-
-		// construct
-		event = PR_NEW(MyEventType);
-		if (event == NULL) goto done;
-
-		// initialize
-		PL_InitEvent(event, owner,
-					 (PLHandleEventProc)handleMyEvent,
-					 (PLDestroyEventProc)destroyMyEvent);
-		event->x = x;
-		event->y = strdup(y);
-
-		// post
-		PL_PostEvent(myQueue, &event->e);
-
-      done:
-		PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
-    }
-
-If you don't call PL_InitEvent and PL_PostEvent within the
-event-queue's monitor, you'll get a big red assert. 
-
-Handling Events
----------------
-
-To handle an event you must write a callback that is passed the event
-record you defined containing the event's arguments:
-
-    void* handleMyEvent(MyEventType* event)
-    {
-		doit(event->x, event->y);
-		return NULL;	// you could return a value for a sync event
-    }
-
-Similarly for the destruction callback:
-
-    void destroyMyEvent(MyEventType* event)
-    {
-		free(event->y);	// created by strdup
-		free(event);
-    }
-
-Processing Events in Your Event Loop
-------------------------------------
-
-If your main loop only processes events delivered to the event queue,
-things are rather simple. You just get the next event (which may
-block), and then handle it:
-
-    while (1) {
-		event = PL_GetEvent(myQueue);
-		PL_HandleEvent(event);
-    }
-
-However, if other things must be waited on, you'll need to obtain a
-file-descriptor that represents your event queue, and hand it to select:
-
-    fd = PL_GetEventQueueSelectFD(myQueue);
-    ...add fd to select set...
-    while (select(...)) {
-		if (...fd...) {
-		    PL_ProcessPendingEvents(myQueue);
-		}
-		...
-    }
-
-Of course, with Motif and Windows it's more complicated than that, and
-on Mac it's completely different, but you get the picture.
-
-Revoking Events
----------------
-If at any time an owner of events is about to be destroyed, you must
-take steps to ensure that no one tries to use the event queue after
-the owner is gone (or a crash may result). You can do this by either
-processing all the events in the queue before destroying the owner:
-
-    {
-		...
-		PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
-		PL_ProcessPendingEvents(myQueue);
-		DestroyMyOwner(owner);
-		PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
-		...
-    }
-
-or by revoking the events that are in the queue for that owner. This
-removes them from the queue and calls their destruction callback:
-
-    {
-		...
-		PL_ENTER_EVENT_QUEUE_MONITOR(myQueue);
-		PL_RevokeEvents(myQueue, owner);
-		DestroyMyOwner(owner);
-		PL_EXIT_EVENT_QUEUE_MONITOR(myQueue);
-		...
-    }
-
-In either case it is essential that you be in the event-queue's monitor
-to ensure that all events are removed from the queue for that owner, 
-and to ensure that no more events will be delivered for that owner.
-**********************************************************************/
-
-#ifndef prevent_h___
-#define prevent_h___
-
-#include "prtypes.h"
-#include "prclist.h"
-#include "prthread.h"
-#include "prmon.h"
-
-/* For HWND */
-#if defined(_WIN32) && !defined(__MINGW32__)
-#include <windef.h>
-#elif defined(WIN16) || defined(__MINGW32__)
-#include <windows.h>
-#elif defined(XP_OS2)
-#define INCL_DOSPROCESS
-#include <os2.h>
-#endif
-
-PR_BEGIN_EXTERN_C
-
-/* Typedefs */
-
-typedef struct PLEvent PLEvent;
-typedef struct PLEventQueue PLEventQueue;
-
-/*******************************************************************************
- * Event Queue Operations
- ******************************************************************************/
-
-/*
-** Creates a new event queue. Returns NULL on failure.
-*/
-PR_EXTERN(PLEventQueue*)
-PL_CreateEventQueue(char* name, PRThread* handlerThread);
-
-
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_CreateNativeEventQueue()
-** 
-** DESCRIPTION:
-** PL_CreateNativeEventQueue() creates an event queue that
-** uses platform specific notify mechanisms.
-** 
-** For Unix, the platform specific notify mechanism provides
-** an FD that may be extracted using the function
-** PL_GetEventQueueSelectFD(). The FD returned may be used in
-** a select() function call.
-** 
-** For Windows, the platform specific notify mechanism
-** provides an event receiver window that is called by
-** Windows to process the event using the windows message
-** pump engine.
-** 
-** INPUTS: 
-**  name:   A name, as a diagnostic aid.
-** 
-**  handlerThread: A pointer to the PRThread structure for
-** the thread that will "handle" events posted to this event
-** queue.
-**
-** RETURNS: 
-** A pointer to a PLEventQueue structure or NULL.
-** 
-*/
-PR_EXTERN(PLEventQueue *) 
-    PL_CreateNativeEventQueue(
-        char *name, 
-        PRThread *handlerThread
-    );
-
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_CreateMonitoredEventQueue()
-** 
-** DESCRIPTION:
-** PL_CreateMonitoredEventQueue() creates an event queue. No
-** platform specific notify mechanism is created with the
-** event queue.
-** 
-** Users of this type of event queue must explicitly poll the
-** event queue to retreive and process events.
-** 
-** 
-** INPUTS: 
-**  name:   A name, as a diagnostic aid.
-** 
-**  handlerThread: A pointer to the PRThread structure for
-** the thread that will "handle" events posted to this event
-** queue.
-**
-** RETURNS: 
-** A pointer to a PLEventQueue structure or NULL.
-** 
-*/
-PR_EXTERN(PLEventQueue *) 
-    PL_CreateMonitoredEventQueue(
-        char *name,
-        PRThread *handlerThread
-    );
-
-/*
-** Destroys an event queue.
-*/
-PR_EXTERN(void)
-PL_DestroyEventQueue(PLEventQueue* self);
-
-/* 
-** Returns the monitor associated with an event queue. This monitor is 
-** selectable. The monitor should be entered to protect against anyone 
-** calling PL_RevokeEvents while the event is trying to be constructed
-** and delivered.
-*/
-PR_EXTERN(PRMonitor*)
-PL_GetEventQueueMonitor(PLEventQueue* self);
-
-#define PL_ENTER_EVENT_QUEUE_MONITOR(queue)	\
-	PR_EnterMonitor(PL_GetEventQueueMonitor(queue))
-
-#define PL_EXIT_EVENT_QUEUE_MONITOR(queue)	\
-	PR_ExitMonitor(PL_GetEventQueueMonitor(queue))
-
-/*
-** Posts an event to an event queue, waking up any threads waiting for an
-** event. If event is NULL, notification still occurs, but no event will
-** be available. 
-**
-** Any events delivered by this routine will be destroyed by PL_HandleEvent
-** when it is called (by the event-handling thread).
-*/
-PR_EXTERN(PRStatus)
-PL_PostEvent(PLEventQueue* self, PLEvent* event);
-
-/*
-** Like PL_PostEvent, this routine posts an event to the event handling
-** thread, but does so synchronously, waiting for the result. The result
-** which is the value of the handler routine is returned.
-**
-** Any events delivered by this routine will be not be destroyed by 
-** PL_HandleEvent, but instead will be destroyed just before the result is
-** returned (by the current thread).
-*/
-PR_EXTERN(void*)
-PL_PostSynchronousEvent(PLEventQueue* self, PLEvent* event);
-
-/*
-** Gets an event from an event queue. Returns NULL if no event is
-** available.
-*/
-PR_EXTERN(PLEvent*)
-PL_GetEvent(PLEventQueue* self);
-
-/*
-** Returns true if there is an event available for PL_GetEvent.
-*/
-PR_EXTERN(PRBool)
-PL_EventAvailable(PLEventQueue* self);
-
-/*
-** This is the type of the function that must be passed to PL_MapEvents
-** (see description below).
-*/
-typedef void 
-(PR_CALLBACK *PLEventFunProc)(PLEvent* event, void* data, PLEventQueue* queue);
-
-/*
-** Applies a function to every event in the event queue. This can be used
-** to selectively handle, filter, or remove events. The data pointer is
-** passed to each invocation of the function fun.
-*/
-PR_EXTERN(void)
-PL_MapEvents(PLEventQueue* self, PLEventFunProc fun, void* data);
-
-/*
-** This routine walks an event queue and destroys any event whose owner is
-** the owner specified. The == operation is used to compare owners.
-*/
-PR_EXTERN(void)
-PL_RevokeEvents(PLEventQueue* self, void* owner);
-
-/*
-** This routine processes all pending events in the event queue. It can be
-** called from the thread's main event-processing loop whenever the event
-** queue's selectFD is ready (returned by PL_GetEventQueueSelectFD).
-*/
-PR_EXTERN(void)
-PL_ProcessPendingEvents(PLEventQueue* self);
-
-/*******************************************************************************
- * Pure Event Queues
- *
- * For when you're only processing PLEvents and there is no native
- * select, thread messages, or AppleEvents.
- ******************************************************************************/
-
-/*
-** Blocks until an event can be returned from the event queue. This routine
-** may return NULL if the current thread is interrupted.
-*/
-PR_EXTERN(PLEvent*)
-PL_WaitForEvent(PLEventQueue* self);
-
-/*
-** One stop shopping if all you're going to do is process PLEvents. Just
-** call this and it loops forever processing events as they arrive. It will
-** terminate when your thread is interrupted or dies.
-*/
-PR_EXTERN(void)
-PL_EventLoop(PLEventQueue* self);
-
-/*******************************************************************************
- * Native Event Queues
- *
- * For when you need to call select, or WaitNextEvent, and yet also want
- * to handle PLEvents.
- ******************************************************************************/
-
-/*
-** This routine allows you to grab the file descriptor associated with an
-** event queue and use it in the readFD set of select. Useful for platforms
-** that support select, and must wait on other things besides just PLEvents.
-*/
-PR_EXTERN(PRInt32)
-PL_GetEventQueueSelectFD(PLEventQueue* self);
-
-/*
-**  This routine will allow you to check to see if the given eventQueue in
-**  on the current thread.  It will return PR_TRUE if so, else it will return
-**  PR_FALSE
-*/
-PR_EXTERN(PRBool)
-    PL_IsQueueOnCurrentThread( PLEventQueue *queue );
-
-/*******************************************************************************
- * Event Operations
- ******************************************************************************/
-
-/*
-** The type of an event handler function. This function is passed as an
-** initialization argument to PL_InitEvent, and called by
-** PL_HandleEvent. If the event is called synchronously, a void* result 
-** may be returned (otherwise any result will be ignored).
-*/
-typedef void*
-(PR_CALLBACK *PLHandleEventProc)(PLEvent* self);
-
-/*
-** The type of an event destructor function. This function is passed as
-** an initialization argument to PL_InitEvent, and called by
-** PL_DestroyEvent.
-*/
-typedef void
-(PR_CALLBACK *PLDestroyEventProc)(PLEvent* self);
-
-/*
-** Initializes an event. Usually events are embedded in a larger event
-** structure which holds event-specific data, so this is an initializer
-** for that embedded part of the structure.
-*/
-PR_EXTERN(void)
-PL_InitEvent(PLEvent* self, void* owner,
-			 PLHandleEventProc handler,
-			 PLDestroyEventProc destructor);
-
-/*
-** Returns the owner of an event. 
-*/
-PR_EXTERN(void*)
-PL_GetEventOwner(PLEvent* self);
-
-/*
-** Handles an event, calling the event's handler routine.
-*/
-PR_EXTERN(void)
-PL_HandleEvent(PLEvent* self);
-
-/*
-** Destroys an event, calling the event's destructor.
-*/
-PR_EXTERN(void)
-PL_DestroyEvent(PLEvent* self);
-
-/*
-** Removes an event from an event queue.
-*/
-PR_EXTERN(void)
-PL_DequeueEvent(PLEvent* self, PLEventQueue* queue);
-
-/*******************************************************************************
- * Private Stuff
- ******************************************************************************/
-
-struct PLEvent {
-    PRCList				link;
-    PLHandleEventProc	handler;
-    PLDestroyEventProc	destructor;
-    void*				owner;
-    void*				synchronousResult;
-    /* other fields follow... */
-};
-
-/******************************************************************************/
-
-/*
-** Returns the event queue associated with the main thread.
-**
-*/
-#ifdef XP_PC
-/* -----------------------------------------------------------------------
-** FUNCTION: PL_GetNativeEventReceiverWindow()
-** 
-** DESCRIPTION:
-** PL_GetNativeEventReceiverWindow() returns the windows
-** handle of the event receiver window associated with the
-** referenced PLEventQueue argument.
-** 
-** INPUTS: 
-**  PLEventQueue pointer
-**
-** RETURNS:
-**  event receiver window handle.
-** 
-** RESTRICTIONS: MS-Windows ONLY.
-** 
-*/
-PR_EXTERN(HWND) 
-    PL_GetNativeEventReceiverWindow( 
-        PLEventQueue *eqp 
-    );
-
-#endif /* XP_PC */
-
-PR_END_EXTERN_C
-
-#endif /* prevent_h___ */
--- a/lib/ds/plvrsion.c
+++ b/lib/ds/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libplds3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplds, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libplds3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/libc/src/plc.rc
+++ b/lib/libc/src/plc.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "plc"
 #define MY_FILEDESCRIPTION "PLC Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
--- a/lib/libc/src/plvrsion.c
+++ b/lib/libc/src/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libplc3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libplc, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libplc3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/prstreams/plvrsion.c
+++ b/lib/prstreams/plvrsion.c
@@ -37,17 +37,24 @@
 #define _PRODUCTION ""
 #endif
 #if defined(DEBUG)
 #define _DEBUG_STRING " (debug)"
 #else
 #define _DEBUG_STRING ""
 #endif
 
-PRVersionDescription prVersionDescription_libprstrms3 =
+/*
+ * A trick to expand the PR_VMAJOR macro before concatenation.
+ */
+#define CONCAT(x, y) x ## y
+#define CONCAT2(x, y) CONCAT(x, y)
+#define VERSION_DESC_NAME CONCAT2(prVersionDescription_libprstrms, PR_VMAJOR)
+
+PRVersionDescription VERSION_DESC_NAME =
 {
     /* version          */  2,                  /* this is the only one supported */
     /* buildTime        */  _BUILD_TIME,        /* usecs since midnight 1/1/1970 GMT */
     /* buildTimeString  */  _BUILD_STRING,       /*    ditto, but human readable */
     /* vMajor           */  PR_VMAJOR,          /* NSPR's version number */
     /* vMinor           */  PR_VMINOR,          /*  and minor version */
     /* vPatch           */  PR_VPATCH,          /*  and patch */
     /* beta             */  PR_BETA,            /* beta build boolean */
@@ -87,13 +94,13 @@ PR_IMPLEMENT(const PRVersionDescription*
      * Add dummy references to rcsid and sccsid to prevent them
      * from being optimized away as unused variables.
      */
     const char *dummy;
     
     dummy = rcsid;
     dummy = sccsid;
 #endif
-    return &prVersionDescription_libprstrms3;
+    return &VERSION_DESC_NAME;
 }  /* versionEntryPointType */
 
 /* plvrsion.c */
 
--- a/lib/prstreams/prstrms.cpp
+++ b/lib/prstreams/prstrms.cpp
@@ -217,17 +217,17 @@ PRfilebuf::underflow()
 
     if ((count=PR_Read(_fd,(void *)base(),blen())) <= 0)
         return EOF;     // reached EOF
     setg(base(),base(),base()+count);
     return (int)(unsigned char) *gptr();
 }
 
 streambuf*	
-PRfilebuf::setbuf(char *buffptr, int bufflen)
+PRfilebuf::setbuf(char *buffptr, PRstreambuflen bufflen)
 {
     if (is_open() && (ebuf()))
         return 0;
     if ((!buffptr) || (bufflen <= 0))
         unbuffered(1);
     else
         setb(buffptr, buffptr+bufflen, 0);
     return this;
--- a/lib/prstreams/prstrms.h
+++ b/lib/prstreams/prstrms.h
@@ -26,16 +26,22 @@
 #include "prtypes.h"
 #include "prio.h"
 
 #ifdef _MSC_VER
 #pragma warning( disable : 4275)
 #endif
 #include <iostream.h>
 
+#if defined(AIX) && defined(__64BIT__)
+typedef long PRstreambuflen;
+#else
+typedef int PRstreambuflen;
+#endif
+
 #if defined (PRFSTREAMS_BROKEN)
 
 // fix it sometime
 
 #define	 PRfilebuf	streambuf
 #define  PRifstream	ifstream
 #define	 PRofstream	ofstream
 #define	 PRfstream	fstream
@@ -46,17 +52,17 @@ class PR_IMPLEMENT(PRfilebuf): public st
 {
 public:
     PRfilebuf();
     PRfilebuf(PRFileDesc *fd);
     PRfilebuf(PRFileDesc *fd, char * buffptr, int bufflen);
     ~PRfilebuf();
     virtual	int	overflow(int=EOF);
     virtual	int	underflow();
-    virtual	streambuf *setbuf(char *buff, int bufflen);
+    virtual	streambuf *setbuf(char *buff, PRstreambuflen bufflen);
     virtual	streampos seekoff(streamoff, ios::seek_dir, int);
     virtual int sync();
     PRfilebuf *open(const char *name, int mode, int flags);
    	PRfilebuf *attach(PRFileDesc *fd);
     PRfilebuf *close();
    	int	is_open() const {return (_fd != 0);}
     PRFileDesc *fd(){return _fd;}
 
--- a/lib/prstreams/prstrms.rc
+++ b/lib/prstreams/prstrms.rc
@@ -17,16 +17,20 @@
  */
 
 #include "prinit.h"
 #include <winver.h>
 
 #define MY_LIBNAME "prstrms"
 #define MY_FILEDESCRIPTION "PRSTRMS Library"
 
+#define STRINGIZE(x) #x
+#define STRINGIZE2(x) STRINGIZE(x)
+#define PR_VMAJOR_STR STRINGIZE2(PR_VMAJOR)
+
 #ifdef _DEBUG
 #define MY_DEBUG_STR " (debug)"
 #define MY_FILEFLAGS_1 VS_FF_DEBUG
 #else
 #define MY_DEBUG_STR ""
 #define MY_FILEFLAGS_1 0x0L
 #endif
 #if PR_BETA
@@ -61,17 +65,17 @@ BEGIN
     BLOCK "StringFileInfo"
     BEGIN
         BLOCK "040904B0" // Lang=US English, CharSet=Unicode
         BEGIN
             VALUE "CompanyName", "Netscape Communications Corporation\0"
             VALUE "FileDescription", MY_FILEDESCRIPTION MY_DEBUG_STR "\0"
             VALUE "FileVersion", PR_VERSION "\0"
             VALUE "InternalName", MY_INTERNAL_NAME "\0"
-            VALUE "LegalCopyright", "Copyright \251 1996-1999 Netscape Communications Corporation\0"
+            VALUE "LegalCopyright", "Copyright \251 1996-2000 Netscape Communications Corporation\0"
             VALUE "OriginalFilename", MY_INTERNAL_NAME ".dll\0"
             VALUE "ProductName", "Netscape Portable Runtime\0"
             VALUE "ProductVersion", PR_VERSION "\0"
         END
     END
     BLOCK "VarFileInfo"
     BEGIN
         VALUE "Translation", 0x409, 1200
index 2a9db190384a307abb3fe799695059371172c175..fa75d4da838d1eb430448e405ea838791c68382a
GIT binary patch
literal 97889
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
--- a/makefile.win
+++ b/makefile.win
@@ -77,17 +77,17 @@ PR_OBJDIR = WIN954.0_OPT.OBJ
 # The rules.  Simply invoke gmake with the same target.
 # The default target is 'all'.  For Win16, set up the
 # environment to use the Watcom compiler, Watcom headers,
 # and Watcom libs.
 #
 
 all:: export libs install
 
-export libs install clobber clobber_all clean::
+export libs install clobber clobber_all clean depend::
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%WATCPATH%
 	set INCLUDE=%WATC_INC%
 	set LIB=%WATC_LIB%
 !endif
 	$(GMAKE) $(GMAKE_FLAGS) $@
 !if "$(MOZ_BITS)" == "16"
 	set PATH=%MSVCPATH%
@@ -98,11 +98,8 @@ export libs install clobber clobber_all 
 !if "$(MOZ_BITS)" != "16"
 export::
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\*.h $(DIST)\include
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\obsolete\*.h $(DIST)\include\obsolete
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\include\private\*.h $(DIST)\include\private
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.lib $(DIST)\lib
 	$(MAKE_INSTALL) $(XPDIST)\$(PR_OBJDIR)\lib\*.dll $(DIST)\bin
 !endif
-
-depend::
-	@echo NSPR20 has no dependencies.  Skipped.
--- a/pr/include/MANIFEST
+++ b/pr/include/MANIFEST
@@ -32,22 +32,21 @@ prprf.h
 prproces.h
 prrng.h
 prrwlock.h
 prshm.h
 prshma.h
 prsystem.h
 prthread.h
 prtime.h
+prtpool.h
 prtrace.h
 prtypes.h
 prvrsion.h
 prwin16.h
 
-prlink_mac.h
-
 obsolete/protypes.h
 obsolete/prsem.h
 obsolete/probslet.h
 
 private/prpriv.h
 private/pprio.h
 private/pprthred.h
--- a/pr/include/md/_aix.h
+++ b/pr/include/md/_aix.h
@@ -54,16 +54,17 @@
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #ifdef _PR_INET6
 #define _PR_HAVE_GETHOSTBYNAME2
 #endif
 #define _PR_HAVE_SYSV_SEMAPHORES
 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 /* Timer operations */
 #if defined(AIX_TIMERS)
 extern PRIntervalTime _MD_AixGetInterval(void);
 #define _MD_GET_INTERVAL _MD_AixGetInterval
 
 extern PRIntervalTime _MD_AixIntervalPerSec(void);
 #define _MD_INTERVAL_PER_SEC _MD_AixIntervalPerSec
--- a/pr/include/md/_aix32.cfg
+++ b/pr/include/md/_aix32.cfg
@@ -68,16 +68,18 @@
 #define PR_ALIGN_OF_FLOAT   4
 #define PR_ALIGN_OF_DOUBLE  4
 #define PR_ALIGN_OF_POINTER 4
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
 #define BYTES_PER_FLOAT		PR_BYTES_PER_FLOAT
--- a/pr/include/md/_aix32in6.cfg
+++ b/pr/include/md/_aix32in6.cfg
@@ -71,16 +71,17 @@
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
 #ifndef _PR_INET6
 #define _PR_INET6
 #endif
+#define PR_AF_INET6 24  /* same as AF_INET6 */
 
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
--- a/pr/include/md/_aix64.cfg
+++ b/pr/include/md/_aix64.cfg
@@ -72,16 +72,17 @@
 
 #define	HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
 #ifndef _PR_INET6
 #define _PR_INET6
 #endif
+#define PR_AF_INET6 24  /* same as AF_INET6 */
 
 #ifndef NO_NSPR_10_SUPPORT
 
 #define BYTES_PER_BYTE		PR_BYTES_PER_BYTE
 #define BYTES_PER_SHORT 	PR_BYTES_PER_SHORT
 #define BYTES_PER_INT 		PR_BYTES_PER_INT
 #define BYTES_PER_INT64		PR_BYTES_PER_INT64
 #define BYTES_PER_LONG		PR_BYTES_PER_LONG
--- a/pr/include/md/_beos.h
+++ b/pr/include/md/_beos.h
@@ -280,32 +280,34 @@ struct protoent* getprotobynumber(int nu
 #define _MD_INIT_IO()
 #define _MD_INIT_FILEDESC(fd)
 
 #define _MD_OPEN_DIR _MD_open_dir
 #define _MD_READ_DIR _MD_read_dir
 #define _MD_CLOSE_DIR _MD_close_dir
 #define _MD_MAKE_NONBLOCK _MD_make_nonblock
 #define _MD_OPEN _MD_open
+#define _MD_OPEN_FILE _MD_open
 #define _MD_CLOSE_FILE _MD_close_file
 #define _MD_READ _MD_read
 #define _MD_WRITE _MD_write
 #define _MD_WRITEV _MD_writev
 #define _MD_LSEEK _MD_lseek
 #define _MD_LSEEK64 _MD_lseek64
 #define _MD_FSYNC _MD_fsync
 #define _MD_DELETE _MD_delete
 #define _MD_GETFILEINFO _MD_getfileinfo
 #define _MD_GETFILEINFO64 _MD_getfileinfo64
 #define _MD_GETOPENFILEINFO _MD_getopenfileinfo
 #define _MD_GETOPENFILEINFO64 _MD_getopenfileinfo64
 #define _MD_RENAME _MD_rename
 #define _MD_ACCESS _MD_access
 #define _MD_STAT stat
 #define _MD_MKDIR _MD_mkdir
+#define _MD_MAKE_DIR _MD_mkdir
 #define _MD_RMDIR _MD_rmdir
 #define _MD_PR_POLL _MD_pr_poll
 
 /* Network I/O */
 
 #define _MD_CLOSE_SOCKET _MD_close_socket
 #define _MD_CONNECT _MD_connect
 #define _MD_ACCEPT _MD_accept
--- a/pr/include/md/_hpux.h
+++ b/pr/include/md/_hpux.h
@@ -43,16 +43,17 @@
 #ifndef HAVE_STRERROR
 #define HAVE_STRERROR
 #endif
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 #undef _PR_HAVE_ATOMIC_OPS
 
 #if !defined(_PR_PTHREADS)
 
 #include <syscall.h>
 #include <setjmp.h>
 
--- a/pr/include/md/_hpux32.cfg
+++ b/pr/include/md/_hpux32.cfg
@@ -25,16 +25,18 @@
 
 #ifndef HPUX
 #define HPUX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_hpux64.cfg
+++ b/pr/include/md/_hpux64.cfg
@@ -26,16 +26,18 @@
 #ifndef HPUX
 #define HPUX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 #define IS_64
 
+#define PR_AF_INET6 22  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_irix.h
+++ b/pr/include/md/_irix.h
@@ -55,16 +55,17 @@
 #define _PR_HAVE_ATOMIC_OPS
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ST_ATIM
 #define _PR_HAVE_OFF64_T
 #define HAVE_POINTER_LOCALTIME_R
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
+#define _PR_ACCEPT_INHERIT_NONBLOCK
 
 /* Initialization entry points */
 NSPR_API(void) _MD_EarlyInit(void);
 #define _MD_EARLY_INIT _MD_EarlyInit
 
 NSPR_API(void) _MD_IrixInit(void);
 #define _MD_FINAL_INIT _MD_IrixInit
 
--- a/pr/include/md/_irix32.cfg
+++ b/pr/include/md/_irix32.cfg
@@ -29,16 +29,18 @@
 
 #ifndef IRIX
 #define IRIX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_irix64.cfg
+++ b/pr/include/md/_irix64.cfg
@@ -30,16 +30,18 @@
 #ifndef IRIX
 #define IRIX
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 #define IS_64
 
+#define PR_AF_INET6 24  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_linux.cfg
+++ b/pr/include/md/_linux.cfg
@@ -22,16 +22,18 @@
 #ifndef XP_UNIX
 #define XP_UNIX
 #endif
 
 #ifndef LINUX
 #define LINUX
 #endif
 
+#define PR_AF_INET6 10  /* same as AF_INET6 */
+
 #ifdef __powerpc__
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN    1
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_linux.h
+++ b/pr/include/md/_linux.h
@@ -65,16 +65,20 @@
 #endif
 #undef _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #if defined(__alpha)
 #define _PR_HAVE_LARGE_OFF_T
 #else
 #define _PR_NO_LARGE_FILES
 #endif
+#ifdef _PR_INET6
+#define _PR_HAVE_GETHOSTBYNAME2
+#define _PR_INET6_PROBE
+#endif
 #define _PR_HAVE_SYSV_SEMAPHORES
 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
 
 #ifdef _PR_PTHREADS
 
 extern void _MD_CleanupBeforeExit(void);
 #define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
 
--- a/pr/include/md/_macos.h
+++ b/pr/include/md/_macos.h
@@ -313,16 +313,17 @@ typedef enum IOOperation {
     READ_ASYNC,
     WRITE_ASYNC
 } IOOperation;
 
 
 #define _MD_INIT_IO()
 
 #define _MD_OPEN 					_MD_Open
+#define _MD_OPEN_FILE 				_MD_Open
 #define _MD_CLOSE_FILE 				FSClose
 #define _MD_READ(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,READ_ASYNC)
 #define _MD_WRITE(fd,buf,amount) 	ReadWriteProc(fd,buf,amount,WRITE_ASYNC)
 #define _MD_WRITE_SYNC(fd,buf,amount) WriteSyncProc(fd,buf,amount)
 #define _MD_GET_FILE_ERROR() 		_PR_MD_CURRENT_THREAD()->md.osErrCode
 #define _MD_LSEEK 					_MD_LSeek
 #define _MD_FSYNC 					_MD_FSync
 
@@ -363,16 +364,17 @@ extern PRStatus _MD_OpenDir(struct _MDDi
 #define	_MD_OPEN_DIR 		_MD_OpenDir
 
 extern char* _MD_ReadDir(struct _MDDir *md,PRIntn flags);
 #define	_MD_READ_DIR 		_MD_ReadDir
 
 #define	_MD_CLOSE_DIR 		_MD_CloseDir
 
 #define	_MD_MKDIR 			_MD_MkDir
+#define	_MD_MAKE_DIR		_MD_MkDir
 #define	_MD_RMDIR 			_MD_Delete
 
 /*
 ** Pipe I/O Related definitions (not implemented)
 */
 
 #define _MD_PIPEAVAILABLE(fd) -1
 
--- a/pr/include/md/_os2.h
+++ b/pr/include/md/_os2.h
@@ -177,32 +177,34 @@ struct _MDProcess {
 };
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
 /* --- IO stuff --- */
 
 #define _MD_OPEN                      (_PR_MD_OPEN)
+#define _MD_OPEN_FILE                 (_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_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_MAKE_DIR                  (_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... */
--- a/pr/include/md/_osf1.cfg
+++ b/pr/include/md/_osf1.cfg
@@ -31,16 +31,18 @@
 #undef  IS_BIG_ENDIAN
 #define	HAVE_LONG_LONG
 #define HAVE_ALIGNED_DOUBLES
 #define HAVE_ALIGNED_LONGLONGS
 #ifndef IS_64
 #define IS_64
 #endif
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_osf1.h
+++ b/pr/include/md/_osf1.h
@@ -41,19 +41,24 @@
 
 #define NEED_TIME_R
 #define USE_DLFCN
 
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
 #define _PR_HAVE_LARGE_OFF_T
-#ifdef _PR_INET6
 #define _PR_HAVE_GETIPNODEBYNAME
 #define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x00000010
+#define AI_ALL      0x00000008
+#define AI_ADDRCONFIG 0x00000020
 #endif
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
 
 #define USE_SETJMP
 
 #include <setjmp.h>
 
--- a/pr/include/md/_solaris.h
+++ b/pr/include/md/_solaris.h
@@ -68,16 +68,25 @@
 #endif
 
 #define _PR_POLL_AVAILABLE
 #define _PR_USE_POLL
 #define _PR_STAT_HAS_ST_ATIM
 #define _PR_HAVE_POSIX_SEMAPHORES
 #define PR_HAVE_POSIX_NAMED_SHARED_MEMORY
 #define _PR_HAVE_GETIPNODEBYNAME
+#define _PR_HAVE_GETIPNODEBYADDR
+#define _PR_INET6_PROBE
+#define _PR_ACCEPT_INHERIT_NONBLOCK
+#ifndef _PR_INET6
+#define AF_INET6 26
+#define AI_V4MAPPED 0x0001 
+#define AI_ALL      0x0002
+#define AI_ADDRCONFIG   0x0004
+#endif
 
 #include "prinrval.h"
 NSPR_API(PRIntervalTime) _MD_Solaris_GetInterval(void);
 #define _MD_GET_INTERVAL                  _MD_Solaris_GetInterval
 NSPR_API(PRIntervalTime) _MD_Solaris_TicksPerSecond(void);
 #define _MD_INTERVAL_PER_SEC              _MD_Solaris_TicksPerSecond
 
 #if defined(_PR_HAVE_ATOMIC_OPS)
--- a/pr/include/md/_solaris32.cfg
+++ b/pr/include/md/_solaris32.cfg
@@ -36,16 +36,18 @@
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define PR_ALIGN_OF_INT64   4
 #define PR_ALIGN_OF_DOUBLE  4
 #else
 #error unknown processor
 #endif
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_solaris64.cfg
+++ b/pr/include/md/_solaris64.cfg
@@ -37,16 +37,18 @@
 #undef  IS_BIG_ENDIAN
 #define PR_ALIGN_OF_INT64   4
 #define PR_ALIGN_OF_DOUBLE  4
 #else
 #error unknown processor
 #endif
 #define IS_64
 
+#define PR_AF_INET6 26  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   8
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   8
--- a/pr/include/md/_unixos.h
+++ b/pr/include/md/_unixos.h
@@ -329,29 +329,31 @@ extern PRInt32 	_PR_UnixSendFile(PRFileD
 
 extern PRStatus _MD_LockFile(PRInt32 osfd);
 extern PRStatus _MD_TLockFile(PRInt32 osfd);
 extern PRStatus _MD_UnlockFile(PRInt32 osfd);
 
 #define _MD_OPEN_DIR(dir, name)		    _MD_open_dir(dir, name)
 #define _MD_CLOSE_DIR(dir)		        _MD_close_dir(dir)
 #define _MD_READ_DIR(dir, flags)	    _MD_read_dir(dir, flags)
-#define _MD_OPEN(name, osflags, mode    )	_MD_open(name, osflags, mode)
+#define _MD_OPEN(name, osflags, mode)	_MD_open(name, osflags, mode)
+#define _MD_OPEN_FILE(name, osflags, mode)	_MD_open(name, osflags, mode)
 extern PRInt32 _MD_read(PRFileDesc *fd, void *buf, PRInt32 amount);
 #define _MD_READ(fd,buf,amount)		    _MD_read(fd,buf,amount)
 extern PRInt32 _MD_write(PRFileDesc *fd, const void *buf, PRInt32 amount);
 #define _MD_WRITE(fd,buf,amount)	    _MD_write(fd,buf,amount)
 #define _MD_DELETE(name)		        _MD_delete(name)
 #define _MD_GETFILEINFO(fn, info)	    _MD_getfileinfo(fn, info)
 #define _MD_GETFILEINFO64(fn, info)	    _MD_getfileinfo64(fn, info)
 #define _MD_GETOPENFILEINFO(fd, info)	_MD_getopenfileinfo(fd, info)
 #define _MD_GETOPENFILEINFO64(fd, info)	_MD_getopenfileinfo64(fd, info)
 #define _MD_RENAME(from, to)		    _MD_rename(from, to)
 #define _MD_ACCESS(name, how)		    _MD_access(name, how)
 #define _MD_MKDIR(name, mode)		    _MD_mkdir(name, mode)
+#define _MD_MAKE_DIR(name, mode)		_MD_mkdir(name, mode)
 #define _MD_RMDIR(name)			        _MD_rmdir(name)
 #define _MD_ACCEPT_READ(sock, newSock, raddr, buf, amount)	_MD_accept_read(sock, newSock, raddr, buf, amount)
 
 #define _MD_LOCKFILE _MD_LockFile
 #define _MD_TLOCKFILE _MD_TLockFile
 #define _MD_UNLOCKFILE _MD_UnlockFile
 
 
--- a/pr/include/md/_unixware7.cfg
+++ b/pr/include/md/_unixware7.cfg
@@ -28,16 +28,18 @@
 #endif
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define HAVE_LONG_LONG
 #undef	HAVE_ALIGNED_DOUBLES
 #undef	HAVE_ALIGNED_LONGLONGS
 
+#define PR_AF_INET6 27  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
 #define PR_BYTES_PER_INT64  8
 #define PR_BYTES_PER_LONG   4
 #define PR_BYTES_PER_FLOAT  4
 #define PR_BYTES_PER_DOUBLE 8
 #define PR_BYTES_PER_WORD   4
--- a/pr/include/md/_win95.cfg
+++ b/pr/include/md/_win95.cfg
@@ -26,16 +26,18 @@
 #ifndef WIN32
 #define WIN32
 #endif
 
 #ifndef WIN95
 #define WIN95
 #endif
 
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
 #if defined(_M_IX86) || defined(_X86_)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_win95.h
+++ b/pr/include/md/_win95.h
@@ -153,35 +153,50 @@ struct _MDFileDesc {
 struct _MDProcess {
     HANDLE handle;
     DWORD id;
 };
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
 /* --- IO stuff --- */
 
 #define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
 #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_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_MAKE_DIR                  _PR_MD_MAKE_DIR
 #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 --- */
 #define _MD_EACCES                WSAEACCES
 #define _MD_EADDRINUSE            WSAEADDRINUSE
--- a/pr/include/md/_winnt.cfg
+++ b/pr/include/md/_winnt.cfg
@@ -26,16 +26,18 @@
 #ifndef WIN32
 #define WIN32
 #endif
 
 #ifndef WINNT
 #define WINNT
 #endif
 
+#define PR_AF_INET6 23  /* same as AF_INET6 */
+
 #if defined(_M_IX86) || defined(_X86_)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 
 #define PR_BYTES_PER_BYTE   1
 #define PR_BYTES_PER_SHORT  2
 #define PR_BYTES_PER_INT    4
--- a/pr/include/md/_winnt.h
+++ b/pr/include/md/_winnt.h
@@ -195,37 +195,52 @@ struct _MDProcess {
     HANDLE handle;
     DWORD id;
 };
 
 
 /* --- Misc stuff --- */
 #define _MD_GET_SP(thread)            (thread)->md.gcContext[6]
 
+/* --- NT security stuff --- */
+
+extern void _PR_NT_InitSids(void);
+extern void _PR_NT_FreeSids(void);
+extern PRStatus _PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL
+);
+extern void _PR_NT_FreeSecurityDescriptorACL(
+    PSECURITY_DESCRIPTOR pSD, PACL pACL);
+
 /* --- IO stuff --- */
 
 extern PRInt32 _md_Associate(HANDLE);
 extern PRInt32 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket);
 
 #define _MD_OPEN                      _PR_MD_OPEN
+#define _MD_OPEN_FILE                 _PR_MD_OPEN_FILE
 #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_CLOSE_FILE(f)             _PR_MD_CLOSE(f, PR_FALSE)
 #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_MAKE_DIR                  _PR_MD_MAKE_DIR
 #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 --- */
 #define _MD_GET_SOCKET_ERROR()    WSAGetLastError()
 #define _MD_SET_SOCKET_ERROR(_err) WSASetLastError(_err)
--- a/pr/include/nspr.h
+++ b/pr/include/nspr.h
@@ -44,11 +44,13 @@
 #include "prproces.h"
 #include "prrng.h"
 #include "prrwlock.h"
 #include "prshm.h"
 #include "prshma.h"
 #include "prsystem.h"
 #include "prthread.h"
 #include "prtime.h"
+#include "prtpool.h"
+#include "prtrace.h"
 #include "prtypes.h"
 
 #endif /* nspr_h___ */
--- a/pr/include/obsolete/probslet.h
+++ b/pr/include/obsolete/probslet.h
@@ -29,27 +29,16 @@
 PR_BEGIN_EXTERN_C
 
 /*
 ** Yield the current thread.  The proper function to use in place of
 ** PR_Yield() is PR_Sleep() with an argument of PR_INTERVAL_NO_WAIT.
 */
 NSPR_API(PRStatus) PR_Yield(void);
 
-/*
-** These are obsolete and are replaced by PR_GetSocketOption() and
-** PR_SetSocketOption().
-*/
-
-NSPR_API(PRStatus) PR_GetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen);
-
-NSPR_API(PRStatus) PR_SetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
-
 /************************************************************************/
 /************* The following definitions are for select *****************/
 /************************************************************************/
 
 /*
 ** The following is obsolete and will be deleted in the next release!
 ** These are provided for compatibility, but are GUARANTEED to be slow.
 **
@@ -155,71 +144,13 @@ NSPR_API(PRInt32)     PR_FD_NISSET(PRInt
 #include <stat.h>
 #else
 #include <sys/stat.h>
 #endif
 
 NSPR_API(PRInt32) PR_Stat(const char *path, struct stat *buf);
 #endif /* NO_NSPR_10_SUPPORT */
 
-/***********************************************************************
-** FUNCTION: PR_CreateNetAddr(), PR_DestroyNetAddr()
-** DESCRIPTION:
-**  Create an instance of a PRNetAddr, assigning well known values as
-**  appropriate.
-**
-** INPUTS
-**  PRNetAddrValue val  The value to be assigned to the IP Address portion
-**                      of the network address. This can only specify the
-**                      special well known values that are equivalent to
-**                      INADDR_ANY and INADDR_LOOPBACK.
-**
-**  PRUInt16 port       The port number to be assigned in the structure.
-**
-** OUTPUTS:
-**  None
-**
-** RETURN:
-**  PRNetAddr *addr     The initialized address that has been allocated
-**                      from the heap. It must be freed by the caller.
-**                      A returned value of zero indicates an error. The
-**                      cause of the error (most likely low memory) may
-**                      be retrieved by calling PR_GetError().
-**
-***********************************************************************/
-NSPR_API(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port);
-NSPR_API(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr);
-
-
-
-/***********************************************************************
-** FUNCTION: PR_GetHostName() **OBSOLETE**
-**   Use PR_GetSystemInfo() (prsystem.h) with an argument of
-**   PR_SI_HOSTNAME instead.
-** DESCRIPTION:	
-** Get the DNS name of the hosting computer.
-**
-** INPUTS:
-**  char *name          The location where the host's name is stored.
-**  PRIntn bufsize      Number of bytes in 'name'.
-** OUTPUTS:
-**  PRHostEnt *name
-**                      This string is filled in by the runtime if the
-**                      function returns PR_SUCCESS. The string must be
-**                      allocated by the caller
-** RETURN:
-**  PRStatus            PR_SUCCESS if the  succeeds. If it fails the
-**                      result will be PR_FAILURE and the reason for
-**                      the failure can be retrieved by PR_GetError().
-***********************************************************************/
-NSPR_API(PRStatus) PR_GetHostName(char *name, PRUint32 namelen);
-
-/*
-** Return the current thread's last error string.
-** obsoleted by PR_GetErrorText().
-*/
-NSPR_API(const char *) PR_GetErrorString(void);
-
 PR_END_EXTERN_C
 
 #endif /* defined(PROBSLET_H) */
 
 /* probslet.h */
--- a/pr/include/obsolete/protypes.h
+++ b/pr/include/obsolete/protypes.h
@@ -127,44 +127,16 @@ typedef PRWord prword_t;
 #define PR_ArenaGrow PL_ArenaGrow
 #define PR_ArenaRelease PL_ArenaRelease
 #define PR_ArenaCountAllocation PL_ArenaCountAllocation
 #define PR_ArenaCountInplaceGrowth PL_ArenaCountInplaceGrowth
 #define PR_ArenaCountGrowth PL_ArenaCountGrowth
 #define PR_ArenaCountRelease PL_ArenaCountRelease
 #define PR_ArenaCountRetract PL_ArenaCountRetract
 
-/* Re: prevent.h->plevent.h */
-#define PREvent PLEvent
-#define PREventQueue PLEventQueue
-#define PR_CreateEventQueue PL_CreateEventQueue
-#define PR_DestroyEventQueue PL_DestroyEventQueue
-#define PR_GetEventQueueMonitor PL_GetEventQueueMonitor
-#define PR_ENTER_EVENT_QUEUE_MONITOR PL_ENTER_EVENT_QUEUE_MONITOR
-#define PR_EXIT_EVENT_QUEUE_MONITOR PL_EXIT_EVENT_QUEUE_MONITOR
-#define PR_PostEvent PL_PostEvent
-#define PR_PostSynchronousEvent PL_PostSynchronousEvent
-#define PR_GetEvent PL_GetEvent
-#define PR_EventAvailable PL_EventAvailable
-#define PREventFunProc PLEventFunProc
-#define PR_MapEvents PL_MapEvents
-#define PR_RevokeEvents PL_RevokeEvents
-#define PR_ProcessPendingEvents PL_ProcessPendingEvents
-#define PR_WaitForEvent PL_WaitForEvent
-#define PR_EventLoop PL_EventLoop
-#define PR_GetEventQueueSelectFD PL_GetEventQueueSelectFD
-#define PRHandleEventProc PLHandleEventProc
-#define PRDestroyEventProc PLDestroyEventProc
-#define PR_InitEvent PL_InitEvent
-#define PR_GetEventOwner PL_GetEventOwner
-#define PR_HandleEvent PL_HandleEvent
-#define PR_DestroyEvent PL_DestroyEvent
-#define PR_DequeueEvent PL_DequeueEvent
-#define PR_GetMainEventQueue PL_GetMainEventQueue
-
 /* Re: prhash.h->plhash.h */
 #define PRHashEntry PLHashEntry
 #define PRHashTable PLHashTable
 #define PRHashNumber PLHashNumber
 #define PRHashFunction PLHashFunction
 #define PRHashComparator PLHashComparator
 #define PRHashEnumerator PLHashEnumerator
 #define PRHashAllocOps PLHashAllocOps
--- a/pr/include/prerr.h
+++ b/pr/include/prerr.h
@@ -215,18 +215,18 @@
 #define PR_END_OF_FILE_ERROR                     (-5938L)
 
 /* Seek error */
 #define PR_FILE_SEEK_ERROR                       (-5937L)
 
 /* The file is busy */
 #define PR_FILE_IS_BUSY_ERROR                    (-5936L)
 
-/* Reserved Error Code -5935 */
-#define PR_RESERVED_ERROR_5935                   (-5935L)
+/* The I/O operation was aborted */
+#define PR_OPERATION_ABORTED_ERROR               (-5935L)
 
 /* Operation is still in progress (probably a non-blocking connect) */
 #define PR_IN_PROGRESS_ERROR                     (-5934L)
 
 /* Operation has already been initiated (probably a non-blocking connect) */
 #define PR_ALREADY_INITIATED_ERROR               (-5933L)
 
 /* The wait group is empty */
--- a/pr/include/prinit.h
+++ b/pr/include/prinit.h
@@ -39,20 +39,19 @@ PR_BEGIN_EXTERN_C
 /*
 ** NSPR's version is used to determine the likelihood that the version you
 ** used to build your component is anywhere close to being compatible with
 ** what is in the underlying library.
 **
 ** The format of the version string is
 **     "<major version>.<minor version> <build date>"
 */
-#define PR_VERSION  "3.5"
-#define PR_VMAJOR   3
-#define PR_VMAJOR_STR "3"
-#define PR_VMINOR   5
+#define PR_VERSION  "4.0"
+#define PR_VMAJOR   4
+#define PR_VMINOR   0
 #define PR_VPATCH   0
 #define PR_BETA     PR_FALSE
 
 /*
 ** PRVersionCheck
 **
 ** The basic signature of the function that is called to provide version
 ** checking. The result will be a boolean that indicates the likelihood
--- a/pr/include/prio.h
+++ b/pr/include/prio.h
@@ -99,43 +99,55 @@ typedef enum PRTransmitFileFlags {
 #define PR_INADDR_ANY (unsigned long)0x00000000
 #define PR_INADDR_LOOPBACK 0x7f000001
 #define PR_INADDR_BROADCAST (unsigned long)0xffffffff
 
 #else /* WIN32 */
 
 #define PR_AF_INET AF_INET
 #define PR_AF_LOCAL AF_UNIX
-#ifdef AF_INET6
-#define PR_AF_INET6 AF_INET6
-#endif
 #define PR_INADDR_ANY INADDR_ANY
 #define PR_INADDR_LOOPBACK INADDR_LOOPBACK
 #define PR_INADDR_BROADCAST INADDR_BROADCAST
 
 #endif /* WIN32 */
 
 /*
+** Define PR_AF_INET6 in prcpucfg.h with the same
+** value as AF_INET6 on platforms with IPv6 support.
+** Otherwise define it here.
+*/
+#ifndef PR_AF_INET6
+#define PR_AF_INET6 100
+#endif
+
+/*
 **************************************************************************
 ** A network address
 **
 ** Only Internet Protocol (IPv4 and IPv6) addresses are supported.
 ** The address family must always represent IPv4 (AF_INET, probably == 2)
 ** or IPv6 (AF_INET6).
 **************************************************************************
 *************************************************************************/
-#if defined(_PR_INET6)
 
-#if !defined(AF_INET6)
-#error "AF_INET6 is not defined"
-#endif
+struct PRIPv6Addr {
+	union {
+		PRUint8  _S6_u8[16];
+		PRUint16 _S6_u16[8];
+		PRUint32 _S6_u32[4];
+		PRUint64 _S6_u64[2];
+	} _S6_un;
+};
+#define pr_s6_addr		_S6_un._S6_u8
+#define pr_s6_addr16	_S6_un._S6_u16
+#define pr_s6_addr32	_S6_un._S6_u32
+#define pr_s6_addr64 	_S6_un._S6_addr64
 
-typedef struct in6_addr PRIPv6Addr;
-
-#endif /* defined(_PR_INET6) */
+typedef struct PRIPv6Addr PRIPv6Addr;
 
 union PRNetAddr {
     struct {
         PRUint16 family;                /* address family (0x00ff maskable) */
 #ifdef XP_BEOS
         char data[10];                  /* Be has a smaller structure */
 #else
         char data[14];                  /* raw address data */
@@ -146,25 +158,23 @@ union PRNetAddr {
         PRUint16 port;                  /* port number */
         PRUint32 ip;                    /* The actual 32 bits of address */
 #ifdef XP_BEOS
         char pad[4];                    /* Be has a smaller structure */
 #else
         char pad[8];
 #endif
     } inet;
-#if defined(_PR_INET6)
     struct {
         PRUint16 family;                /* address family (AF_INET6) */
         PRUint16 port;                  /* port number */
         PRUint32 flowinfo;              /* routing information */
         PRIPv6Addr ip;                  /* the actual 128 bits of address */
         PRUint32 scope_id;              /* set of interfaces for a scope */
     } ipv6;
-#endif /* defined(_PR_INET6) */
 #if defined(XP_UNIX)
     struct {                            /* Unix domain socket address */
         PRUint16 family;                /* address family (AF_UNIX) */
         char path[104];                 /* null-terminated pathname */
     } local;
 #endif
 };
 
@@ -176,22 +186,27 @@ union PRNetAddr {
 
 #if defined(_PR_INET6)
 
 #define PR_NETADDR_SIZE(_addr) PR_NetAddrSize(_addr)
 
 #else
 
 #if defined(XP_UNIX)
-#define PR_NETADDR_SIZE(_addr) \
-        ((_addr)->raw.family == AF_UNIX \
-        ? sizeof((_addr)->local) \
-        : sizeof((_addr)->inet))
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : ((_addr)->raw.family == PR_AF_INET6	\
+        ? sizeof((_addr)->ipv6)					\
+        : sizeof((_addr)->local)))
 #else
-#define PR_NETADDR_SIZE(_addr) sizeof((_addr)->inet)
+#define PR_NETADDR_SIZE(_addr) 					\
+        ((_addr)->raw.family == PR_AF_INET		\
+        ? sizeof((_addr)->inet)					\
+        : sizeof((_addr)->ipv6))
 #endif /* defined(XP_UNIX) */
 
 #endif /* defined(_PR_INET6) */
 
 /*
 ***************************************************************************
 ** PRSockOption
 **
@@ -346,20 +361,16 @@ typedef PRInt16 (PR_CALLBACK *PRPollFN)(
 typedef PRInt32 (PR_CALLBACK *PRAcceptreadFN)(
     PRFileDesc *sd, PRFileDesc **nd, PRNetAddr **raddr,
     void *buf, PRInt32 amount, PRIntervalTime t);
 typedef PRInt32 (PR_CALLBACK *PRTransmitfileFN)(
      PRFileDesc *sd, PRFileDesc *fd, const void *headers,
      PRInt32 hlen, PRTransmitFileFlags flags, PRIntervalTime t);
 typedef PRStatus (PR_CALLBACK *PRGetsocknameFN)(PRFileDesc *fd, PRNetAddr *addr);
 typedef PRStatus (PR_CALLBACK *PRGetpeernameFN)(PRFileDesc *fd, PRNetAddr *addr);
-typedef PRStatus (PR_CALLBACK *PRGetsockoptFN)(  /* OBSOLETE */
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32 *optlen);
-typedef PRStatus (PR_CALLBACK *PRSetsockoptFN)(  /* OBSOLETE */
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen);
 typedef PRStatus (PR_CALLBACK *PRGetsocketoptionFN)(
     PRFileDesc *fd, PRSocketOptionData *data);
 typedef PRStatus (PR_CALLBACK *PRSetsocketoptionFN)(
     PRFileDesc *fd, const PRSocketOptionData *data);
 typedef PRInt32 (PR_CALLBACK *PRSendfileFN)(
 	PRFileDesc *networkSocket, PRSendFileData *sendData,
 	PRTransmitFileFlags flags, PRIntervalTime timeout);
 typedef PRIntn (PR_CALLBACK *PRReservedFN)(PRFileDesc *fd);
@@ -386,18 +397,18 @@ struct PRIOMethods {
     PRSendFN send;                  /* Send all the bytes specified             */
     PRRecvfromFN recvfrom;          /* Solicit (net) bytes and report source    */
     PRSendtoFN sendto;              /* Send bytes to (net) address specified    */
     PRPollFN poll;                  /* Test the fd to see if it is ready        */
     PRAcceptreadFN acceptread;      /* Accept and read on a new (net) fd        */
     PRTransmitfileFN transmitfile;  /* Transmit at entire file                  */
     PRGetsocknameFN getsockname;    /* Get (net) address associated with fd     */
     PRGetpeernameFN getpeername;    /* Get peer's (net) address                 */
-    PRGetsockoptFN getsockopt;      /*             OBSOLETE                     */
-    PRSetsockoptFN setsockopt;      /*             OBSOLETE                     */
+    PRReservedFN reserved_fn_6;     /* reserved for future use */
+    PRReservedFN reserved_fn_5;     /* reserved for future use */
     PRGetsocketoptionFN getsocketoption;
                                     /* Get current setting of specified option  */
     PRSetsocketoptionFN setsocketoption;
                                     /* Set value of specified option            */
     PRSendfileFN sendfile;			/* Send a (partial) file with header/trailer*/
     PRReservedFN reserved_fn_4;		/* reserved for future use */
     PRReservedFN reserved_fn_3;		/* reserved for future use */
     PRReservedFN reserved_fn_2;		/* reserved for future use */
@@ -569,45 +580,73 @@ NSPR_API(PRFileDesc*) PR_PopIOLayer(PRFi
  * RESTRICTIONS:
  * MEMORY:
  *     The return value, if not NULL, points to a dynamically allocated
  *     PRFileDesc object.
  * ALGORITHM:
  **************************************************************************
  */
 
-NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
 /* Open flags */
 #define PR_RDONLY       0x01
 #define PR_WRONLY       0x02
 #define PR_RDWR         0x04
 #define PR_CREATE_FILE  0x08
 #define PR_APPEND       0x10
 #define PR_TRUNCATE     0x20
 #define PR_SYNC         0x40
 #define PR_EXCL         0x80
 
 /*
 ** File modes ....
 **
-** CAVEAT: 'mode' is currently only applicable on UNIX platforms. We are
-** still in the process of seeing how these apply to other file systems.
+** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
+** The 'mode' argument may be ignored by PR_Open on other platforms.
 **
 **   00400   Read by owner.
 **   00200   Write by owner.
 **   00100   Execute (search if a directory) by owner.
 **   00040   Read by group.
 **   00020   Write by group.
 **   00010   Execute by group.
 **   00004   Read by others.
 **   00002   Write by others
 **   00001   Execute by others.
 **
 */
 
+NSPR_API(PRFileDesc*) PR_Open(const char *name, PRIntn flags, PRIntn mode);
+
+/*
+ **************************************************************************
+ * FUNCTION: PR_OpenFile
+ * DESCRIPTION:
+ *     Open a file for reading, writing, or both.
+ *     PR_OpenFile has the same prototype as PR_Open but implements
+ *     the specified file mode where possible.
+ **************************************************************************
+ */
+
+/* File mode bits */
+#define PR_IRWXU 00700  /* read, write, execute/search by owner */
+#define PR_IRUSR 00400  /* read permission, owner */
+#define PR_IWUSR 00200  /* write permission, owner */
+#define PR_IXUSR 00100  /* execute/search permission, owner */
+#define PR_IRWXG 00070  /* read, write, execute/search by group */
+#define PR_IRGRP 00040  /* read permission, group */
+#define PR_IWGRP 00020  /* write permission, group */
+#define PR_IXGRP 00010  /* execute/search permission, group */
+#define PR_IRWXO 00007  /* read, write, execute/search by others */
+#define PR_IROTH 00004  /* read permission, others */
+#define PR_IWOTH 00002  /* write permission, others */
+#define PR_IXOTH 00001  /* execute/search permission, others */
+
+NSPR_API(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode);
+
 /*
  **************************************************************************
  * FUNCTION: PR_Close
  * DESCRIPTION:
  *     Close a file or socket.
  * INPUTS:
  *     PRFileDesc *fd
  *         a pointer to a PRFileDesc.
@@ -1034,16 +1073,28 @@ NSPR_API(PRStatus) PR_CloseDir(PRDir *di
  *        trieved using PR_GetError().
  *************************************************************************
  */
 
 NSPR_API(PRStatus) PR_MkDir(const char *name, PRIntn mode);
 
 /*
  *************************************************************************
+ * FUNCTION: PR_MakeDir
+ * DESCRIPTION:
+ *     Create a new directory with the given name and access mode.
+ *     PR_MakeDir has the same prototype as PR_MkDir but implements
+ *     the specified access mode where possible.
+ *************************************************************************
+ */
+
+NSPR_API(PRStatus) PR_MakeDir(const char *name, PRIntn mode);
+
+/*
+ *************************************************************************
  * FUNCTION: PR_RmDir
  * DESCRIPTION:
  *     Remove a directory by the given name.
  * INPUTS:
  *     const char *name
  *        The name of the directory to be removed. All the path components
  *        must already exist. Only the leaf component will be removed.
  * OUTPUTS:
@@ -1524,17 +1575,18 @@ NSPR_API(PRInt32) PR_SendFile(
 **
 ** INPUTS:
 **    PRFileDesc *listenSock
 **        A socket descriptor that has been called with the PR_Listen() 
 **        function, also known as the rendezvous socket.
 **    void *buf
 **        A pointer to a buffer to receive data sent by the client.  This 
 **        buffer must be large enough to receive <amount> bytes of data
-**        and two PRNetAddr structures, plus an extra 32 bytes.
+**        and two PRNetAddr structures, plus an extra 32 bytes. See:
+**        PR_ACCEPT_READ_BUF_OVERHEAD.
 **    PRInt32 amount
 **        The number of bytes of client data to receive.  Does not include
 **        the size of the PRNetAddr structures.  If 0, no data will be read
 **        from the client.
 **    PRIntervalTime timeout
 **        The timeout interval only applies to the read portion of the 
 **        operation.  PR_AcceptRead will block indefinitely until the 
 **        connection is accepted; the read will timeout after the timeout 
@@ -1547,17 +1599,26 @@ NSPR_API(PRInt32) PR_SendFile(
 **        The address of the remote socket.  This parameter will only be
 **        valid if the function return does not indicate failure.  The
 **        returned address is not guaranteed to be properly aligned.
 ** 
 ** RETURNS:
 **     The number of bytes read from the client or -1 on failure.  The reason 
 **     for the failure is obtained by calling PR_GetError().
 **************************************************************************
-**/
+**/       
+/* define buffer overhead constant. Add this value to the user's 
+** data length when allocating a buffer to accept data.
+**    Example:
+**    #define USER_DATA_SIZE 10
+**    char buf[USER_DATA_SIZE + PR_ACCEPT_READ_BUF_OVERHEAD];
+**    bytesRead = PR_AcceptRead( s, fd, &a, &p, USER_DATA_SIZE, ...);
+*/
+#define PR_ACCEPT_READ_BUF_OVERHEAD (32+(2*sizeof(PRNetAddr)))
+
 NSPR_API(PRInt32) PR_AcceptRead(
     PRFileDesc *listenSock, PRFileDesc **acceptedSock,
     PRNetAddr **peerAddr, void *buf, PRInt32 amount, PRIntervalTime timeout);
 
 /*
 *************************************************************************
 ** FUNCTION: PR_NewTCPSocketPair
 ** DESCRIPTION:
--- a/pr/include/pripcsem.h
+++ b/pr/include/pripcsem.h
@@ -33,16 +33,17 @@
  * Because POSIX named semaphores have kernel persistence,
  * we are forced to have a delete function in this API.
  */
 
 #ifndef pripcsem_h___
 #define pripcsem_h___
 
 #include "prtypes.h"
+#include "prio.h"
 
 PR_BEGIN_EXTERN_C
 
 /*
  * PRSem is an opaque structure that represents a named
  * semaphore.
  */
 typedef struct PRSem PRSem;
--- a/pr/include/private/pprio.h
+++ b/pr/include/private/pprio.h
@@ -203,32 +203,29 @@ NSPR_API(PRFileDesc*)	PR_NTFast_Accept(P
 **    so that the socket can make general purpose socket calls.
 **    Without calling this, the only operations supported on the socket
 **    Are PR_Read, PR_Write, PR_Transmitfile, and PR_Close.
 */
 NSPR_API(void) PR_NTFast_UpdateAcceptContext(PRFileDesc *acceptSock, 
                                         PRFileDesc *listenSock);
 
 
-/* FUNCTION: PR_NT_UseNonblock
-** DESCRIPTION:
-**    This function only works on NT.  It tells nspr to use nonblocking io
-**    rather than async IO.  There is no way to use some of each.  This 
-**    function should be called immediately after calling PR_Init().
-**
-**    WARNING: THIS FUNCTION IS A TEMPORARY HACK AND WILL BE REMOVED SHORTLY
-**    (LIKE ALL FUNCTIONS IN THE PRIVATE AREA).  DO NOT USE THIS FUNCTION AT
-**    ALL WITHOUT CONTACTING mbelshe@netscape.com.
-*/
-NSPR_API(void) PR_NT_UseNonblock();
-
 /* FUNCTION: PR_NT_CancelIo
 ** DESCRIPTION:
 **    Cancel IO operations on fd.
 */
 NSPR_API(PRStatus) PR_NT_CancelIo(PRFileDesc *fd);
 
 
 #endif /* WIN32 */
 
+/*
+** Need external access to this on Mac so we can first set up our faux
+** environment vars
+*/
+#ifdef XP_MAC
+NSPR_API(void) PR_Init_Log(void);
+#endif
+
+
 PR_END_EXTERN_C
 
 #endif /* pprio_h___ */
--- a/pr/include/private/primpl.h
+++ b/pr/include/private/primpl.h
@@ -181,21 +181,16 @@ struct _PT_Notified
 #define PT_THREAD_RESUMED   0x80    /* thread has been resumed */
 #define PT_THREAD_SETGCABLE 0x100   /* set the GCAble flag */
 
 #if defined(DEBUG)
 
 typedef struct PTDebug
 {
     PRTime timeStarted;
-    PRUintn predictionsFoiled;
-    PRUintn pollingListMax;
-    PRUintn continuationsServed;
-    PRUintn recyclesNeeded;
-    PRUintn quiescentIO;
     PRUintn locks_created, locks_destroyed;
     PRUintn locks_acquired, locks_released;
     PRUintn cvars_created, cvars_destroyed;
     PRUintn cvars_notified, delayed_cv_deletes;
 } PTDebug;
 
 NSPR_API(void) PT_GetStats(PTDebug* here);
 NSPR_API(void) PT_FPrintStats(PRFileDesc *fd, const char *msg);
@@ -1030,16 +1025,19 @@ extern void _PR_MD_FREE_FILEDESC(PRFileD
 
 extern void _PR_MD_MAKE_NONBLOCK(PRFileDesc *fd);
 #define    _PR_MD_MAKE_NONBLOCK _MD_MAKE_NONBLOCK
 
 /* File I/O related */
 extern PRInt32 _PR_MD_OPEN(const char *name, PRIntn osflags, PRIntn mode);
 #define    _PR_MD_OPEN _MD_OPEN
 
+extern PRInt32 _PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode);
+#define    _PR_MD_OPEN_FILE _MD_OPEN_FILE
+
 extern PRInt32 _PR_MD_CLOSE_FILE(PRInt32 osfd);
 #define    _PR_MD_CLOSE_FILE _MD_CLOSE_FILE
 
 extern PRInt32 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 amount);
 #define    _PR_MD_READ _MD_READ
 
 extern PRInt32 _PR_MD_WRITE(PRFileDesc *fd, const void *buf, PRInt32 amount);
 #define    _PR_MD_WRITE _MD_WRITE
@@ -1062,16 +1060,19 @@ extern PRInt32 _PR_MD_ACCESS(const char 
 #define _PR_MD_ACCESS _MD_ACCESS
 
 extern PRInt32 _PR_MD_STAT(const char *name, struct stat *buf);
 #define _PR_MD_STAT _MD_STAT
 
 extern PRInt32 _PR_MD_MKDIR(const char *name, PRIntn mode);
 #define _PR_MD_MKDIR _MD_MKDIR
 
+extern PRInt32 _PR_MD_MAKE_DIR(const char *name, PRIntn mode);
+#define _PR_MD_MAKE_DIR _MD_MAKE_DIR
+
 extern PRInt32 _PR_MD_RMDIR(const char *name);
 #define _PR_MD_RMDIR _MD_RMDIR
 
 /* Socket I/O related */
 extern void _PR_MD_INIT_IO(void);
 #define    _PR_MD_INIT_IO _MD_INIT_IO
 
 extern PRInt32 _PR_MD_CLOSE_SOCKET(PRInt32 osfd);
@@ -1416,19 +1417,17 @@ struct PRThread {
     PRInt32 errorStringSize;        /* byte length of current error string | zero */
     PRErrorCode errorCode;          /* current NSPR error code | zero */
     PRInt32 osErrorCode;            /* mapping of errorCode | zero */
     char *errorString;              /* current error string | NULL */
 
 #if defined(_PR_PTHREADS)
     pthread_t id;                   /* pthread identifier for the thread */
     PRBool okToDelete;              /* ok to delete the PRThread struct? */
-    PRCondVar *io_cv;               /* a condition used to run i/o */
     PRCondVar *waiting;             /* where the thread is waiting | NULL */
-	PRIntn io_tq_index;             /* the io-queue index for this thread */
     void *sp;                       /* recorded sp for garbage collection */
     PRThread *next, *prev;          /* simple linked list of all threads */
     PRUint32 suspend;               /* used to store suspend and resume flags */
 #ifdef PT_NO_SIGTIMEDWAIT
     pthread_mutex_t suspendResumeMutex;
     pthread_cond_t suspendResumeCV;
 #endif
     PRUint32 interrupt_blocked;     /* interrupt blocked */
@@ -1544,46 +1543,18 @@ struct PRFileMap {
 
 struct PRFilePrivate {
     PRInt32 state;
     PRBool nonblocking;
     PRBool inheritable;
     PRFileDesc *next;
     PRIntn lockCount;
     _MDFileDesc md;
-#ifdef _PR_PTHREADS
-    PRIntn eventMask[1];   /* An array of _pt_tq_count bitmasks.
-                            * eventMask[i] is only accessed by
-                            * the i-th i/o continuation thread.
-                            * A 0 in a bitmask means the event
-                            * should be igored in the revents
-                            * bitmask returned by poll.
-                            *
-                            * poll's revents bitmask is a short,
-                            * but we need to declare eventMask
-                            * as an array of PRIntn's so that
-                            * each bitmask can be updated
-                            * individually without disturbing
-                            * adjacent memory.  Only the lower
-                            * 16 bits of each PRIntn are used. */
-#endif
-/* IMPORTANT: eventMask MUST BE THE LAST FIELD OF THIS STRUCTURE */
 };
 
-/*
- * The actual size of the PRFilePrivate structure,
- * including the eventMask array at the end
- */
-#ifdef _PR_PTHREADS
-extern PRIntn _pt_tq_count;
-#define PRFILEPRIVATE_SIZE (sizeof(PRFilePrivate) + (_pt_tq_count-1) * sizeof(PRIntn))
-#else
-#define PRFILEPRIVATE_SIZE sizeof(PRFilePrivate)
-#endif
-
 struct PRDir {
     PRDirEntry d;
     _MDDir md;
 };
 
 extern void _PR_InitSegs(void);
 extern void _PR_InitStacks(void);
 extern void _PR_InitTPD(void);
@@ -1669,20 +1640,16 @@ extern PRLogModuleInfo *_pr_linker_lm;
 extern PRLogModuleInfo *_pr_sched_lm;
 extern PRLogModuleInfo *_pr_thread_lm;
 extern PRLogModuleInfo *_pr_gc_lm;
 
 extern PRFileDesc *_pr_stdin;
 extern PRFileDesc *_pr_stdout;
 extern PRFileDesc *_pr_stderr;
 
-#if defined(_PR_INET6)
-extern PRBool _pr_ipv6_enabled;  /* defined in prnetdb.c */
-#endif
-
 /* Overriding malloc, free, etc. */
 #if !defined(_PR_NO_PREEMPT) && defined(XP_UNIX) \
         && !defined(_PR_PTHREADS) && !defined(_PR_GLOBAL_THREADS_ONLY) \
         && !defined(PURIFY) \
         && !defined(RHAPSODY) \
         && !defined(NEXTSTEP) \
         && !defined(QNX) \
         && !(defined (UNIXWARE) && defined (USE_SVR4_THREADS))
deleted file mode 100644
--- a/pr/include/prlink_mac.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/*
- * The contents of this file are subject to the Netscape Public License
- * Version 1.1 (the "NPL"); you may not use this file except in
- * compliance with the NPL.  You may obtain a copy of the NPL at
- * http://www.mozilla.org/NPL/
- * 
- * Software distributed under the NPL is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
- * for the specific language governing rights and limitations under the
- * NPL.
- * 
- * The Initial Developer of this code under the NPL is Netscape
- * Communications Corporation.  Portions created by Netscape are
- * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
- * Reserved.
- */
-
-
-#ifndef prlink_mac_h___
-#define prlink_mac_h___
-
-#ifdef XP_MAC
-
-#include <Files.h>
-#include "prtypes.h"
-
-PR_BEGIN_EXTERN_C
-
-/*
-** PR_LoadNamedFragment
-** 
-** Load a code fragment by fragment name from the data fork of the specified file.
-** The fragment name is an internal name which uniquely identifies a code
-** fragment; this call opens the 'cfrg' resource in the file to find the
-** offsets of the named fragment.
-** 
-** If the specified fragment exists, it is loaded and an entry created
-** in the load map (keyed by fragment name).
-** 
-** If fileSpec points to an alias, the alias is resolved by this call.
-*/
-NSPR_API(PRLibrary*) PR_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName);
-
-/*
-** PR_LoadIndexedFragment
-** 
-** Load a code fragment by fragment index from the data fork of the specified file
-** (since Mac shared libraries can contain multiple code fragments).
-** This call opens the 'cfrg' resource in the file to find the offsets
-** of the named fragment.
-** 
-** If the specified fragment exists, it is loaded and an entry created
-** in the load map (keyed by fragment name).
-** 
-** If fileSpec points to an alias, the alias is resolved by this call.
-** 
-*/
-NSPR_API(PRLibrary*) PR_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex);
-
-PR_END_EXTERN_C
-
-#endif
-
-
-#endif /* prlink_mac_h___ */
--- a/pr/include/prlog.h
+++ b/pr/include/prlog.h
@@ -165,22 +165,16 @@ NSPR_API(void) PR_SetLogBuffering(PRIntn
 */
 NSPR_API(void) PR_LogPrint(const char *fmt, ...);
 
 /*
 ** Flush the log to its file.
 */
 NSPR_API(void) PR_LogFlush(void);
 
-/* Need external access to this on Mac so we can first set up our faux environment vars */
-#ifdef XP_MAC
-NSPR_API(void) PR_Init_Log(void);
-#endif
-
-
 /*
 ** Windoze 16 can't support a large static string space for all of the
 ** various debugging strings so logging is not enabled for it.
 */
 #if (defined(DEBUG) || defined(FORCE_PR_LOG)) && !defined(WIN16)
 #define PR_LOGGING 1
 
 #define PR_LOG_TEST(_module,_level) \
--- a/pr/include/prlong.h
+++ b/pr/include/prlong.h
@@ -183,20 +183,20 @@ NSPR_API(PRInt64) LL_Zero(void);
 #define LL_INIT(hi, lo) {PR_INT32(hi), PR_INT32(lo)}
 #endif
 
 #define LL_IS_ZERO(a)        (((a).hi == 0) && ((a).lo == 0))
 #define LL_EQ(a, b)        (((a).hi == (b).hi) && ((a).lo == (b).lo))
 #define LL_NE(a, b)        (((a).hi != (b).hi) || ((a).lo != (b).lo))
 #define LL_GE_ZERO(a)        (((a).hi >> 31) == 0)
 
-#define LL_CMP(a, op, b)    (((PRInt32)(a).hi op (PRInt32)(b).hi) || \
-                 (((a).hi == (b).hi) && ((a).lo op (b).lo)))
-#define LL_UCMP(a, op, b)    (((a).hi op (b).hi) || \
-                 (((a).hi == (b).hi) && ((a).lo op (b).lo)))
+#define LL_CMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+                 ((PRInt32)(a).hi op (PRInt32)(b).hi))
+#define LL_UCMP(a, op, b)    (((a).hi == (b).hi) ? ((a).lo op (b).lo) : \
+                 ((a).hi op (b).hi))
 
 #define LL_AND(r, a, b)        ((r).lo = (a).lo & (b).lo, \
                  (r).hi = (a).hi & (b).hi)
 #define LL_OR(r, a, b)        ((r).lo = (a).lo | (b).lo, \
                  (r).hi = (a).hi | (b).hi)
 #define LL_XOR(r, a, b)        ((r).lo = (a).lo ^ (b).lo, \
                  (r).hi = (a).hi ^ (b).hi)
 #define LL_OR2(r, a)        ((r).lo = (r).lo | (a).lo, \
--- a/pr/include/prnetdb.h
+++ b/pr/include/prnetdb.h
@@ -112,23 +112,21 @@ NSPR_API(PRStatus) PR_GetHostByName(
 **                      the function returns PR_SUCCESS. This structure
 **                      is allocated by the caller.
 ** RETURN:
 **  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
 **                      the result will be PR_FAILURE and the reason
 **                      for the failure can be retrieved by PR_GetError().
 ***********************************************************************/
 
-/*
- * #define PR_AI_ALL        0x08
- * #define PR_AI_V4MAPPED   0x10
- * #define PR_AI_ADDRCONFIG 0x20
- * #define PR_AI_DEFAULT    (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
- */
-#define PR_AI_DEFAULT 0x30
+
+#define PR_AI_ALL        0x08
+#define PR_AI_V4MAPPED   0x10
+#define PR_AI_ADDRCONFIG 0x20
+#define PR_AI_DEFAULT    (PR_AI_V4MAPPED | PR_AI_ADDRCONFIG)
 
 NSPR_API(PRStatus) PR_GetIPNodeByName(
     const char *hostname,
     PRUint16 af,
     PRIntn flags,
     char *buf,
     PRIntn bufsize,
     PRHostEnt *hostentry);
@@ -212,17 +210,18 @@ NSPR_API(PRIntn) PR_EnumerateHostEnt(
 **  PRStatus            To indicate success or failure. If the latter, the
 **                      reason for the failure can be retrieved by calling
 **                      PR_GetError();
 ***********************************************************************/
 typedef enum PRNetAddrValue
 {
     PR_IpAddrNull,      /* do NOT overwrite the IP address */
     PR_IpAddrAny,       /* assign logical INADDR_ANY to IP address */
-    PR_IpAddrLoopback   /* assign logical INADDR_LOOPBACK */
+    PR_IpAddrLoopback,  /* assign logical INADDR_LOOPBACK  */
+    PR_IpAddrV4Mapped   /* IPv4 mapped address */
 } PRNetAddrValue;
 
 NSPR_API(PRStatus) PR_InitializeNetAddr(
     PRNetAddrValue val, PRUint16 port, PRNetAddr *addr);
 
 /***********************************************************************
 ** FUNCTION: PR_SetNetAddr(), 
 ** DESCRIPTION:
@@ -262,16 +261,33 @@ NSPR_API(PRStatus) PR_SetNetAddr(
 **
 ** RETURN:
 **  PRBool                  PR_TRUE if the network address is of the
 **                          specified type, else PR_FALSE.
 ***********************************************************************/
 NSPR_API(PRBool) PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val);
 
 /***********************************************************************
+** FUNCTION:	
+** DESCRIPTION:	PR_ConvertIPv4AddrToIPv6()
+** Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+**
+** INPUTS:
+**  PRUint32 	v4addr		IPv4 address
+**
+** OUTPUTS:
+**  PRIPv6Addr *v6addr      The converted IPv6 address
+**
+** RETURN:
+**  void
+**                       
+***********************************************************************/
+NSPR_API(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr);
+
+/***********************************************************************
 ** MACRO:	
 ** DESCRIPTION:	PR_NetAddrFamily()
 ** Get the 'family' field of a PRNetAddr union.
 **
 ** INPUTS:
 **  const PRNetAddr *addr   A network address.
 **
 ** RETURN:
@@ -285,22 +301,18 @@ NSPR_API(PRBool) PR_IsNetAddrType(const 
 ** Get the 'port' field of a PRNetAddr union.
 **
 ** INPUTS:
 **  const PRNetAddr *addr   A network address.
 **
 ** RETURN:
 **  PRUint16                The 'port' field of 'addr'.
 ***********************************************************************/
-#ifdef _PR_INET6
 #define PR_NetAddrInetPort(addr) \
     ((addr)->raw.family == PR_AF_INET6 ? (addr)->ipv6.port : (addr)->inet.port)
-#else
-#define PR_NetAddrInetPort(addr) ((addr)->inet.port)
-#endif
 
 /***********************************************************************
 ** FUNCTION:	
 ** DESCRIPTION:	PR_GetProtoByName()
 ** Lookup a protocol entry based on protocol's name
 **
 ** INPUTS:
 **  char *protocolname  Character string of the protocol's name.
@@ -353,38 +365,16 @@ NSPR_API(PRStatus) PR_GetProtoByName(
 **  PRStatus            PR_SUCCESS if the lookup succeeds. If it fails
 **                      the result will be PR_FAILURE and the reason
 **                      for the failure can be retrieved by PR_GetError().
 ***********************************************************************/
 NSPR_API(PRStatus) PR_GetProtoByNumber(
     PRInt32 protocolnumber, char* buffer, PRInt32 bufsize, PRProtoEnt* result);
 
 /***********************************************************************
-** FUNCTION:	
-** DESCRIPTION:	PR_SetIPv6Enable()
-**  Enable IPv6 capability on a platform that supports the architecture.
-**
-**  Note: IPv6 must first be enabled for the host platform. If it is not,
-**        the function will always return PR_FAILURE on any attempt to
-**        change the setting.
-**
-** INPUTS:
-**  PRBool itIs
-**                      Assign it a value of PR_TRUE to turn on IPv6
-**                      addressing, PR_FALSE to turn it off.
-** RETURN:
-**  PRStatus            PR_SUCCESS if the IPv6 is enabled for this particular
-**                      host. Otherwise it will return failure and GetError()
-**                      will confirm the result by indicating that the
-**                      protocol is not supported
-**                      (PR_PROTOCOL_NOT_SUPPORTED_ERROR) 
-***********************************************************************/
-NSPR_API(PRStatus) PR_SetIPv6Enable(PRBool itIs);
-
-/***********************************************************************
 ** FUNCTIONS: PR_ntohs, PR_ntohl, PR_ntohll, PR_htons, PR_htonl, PR_htonll
 **
 ** DESCRIPTION: API entries for the common byte ordering routines.
 **
 **      PR_ntohs        16 bit conversion from network to host
 **      PR_ntohl        32 bit conversion from network to host
 **      PR_ntohll       64 bit conversion from network to host
 **      PR_htons        16 bit conversion from host to network
@@ -394,19 +384,11 @@ NSPR_API(PRStatus) PR_SetIPv6Enable(PRBo
 ***********************************************************************/
 NSPR_API(PRUint16) PR_ntohs(PRUint16);
 NSPR_API(PRUint32) PR_ntohl(PRUint32);
 NSPR_API(PRUint64) PR_ntohll(PRUint64);
 NSPR_API(PRUint16) PR_htons(PRUint16);
 NSPR_API(PRUint32) PR_htonl(PRUint32);
 NSPR_API(PRUint64) PR_htonll(PRUint64);
 
-/***********************************************************************
-** FUNCTION: PR_FamilyInet
-**
-** DESCRIPTION: Routine to get value of address family for Internet Protocol
-**
-***********************************************************************/
-NSPR_API(PRUint16) PR_FamilyInet(void);
-
 PR_END_EXTERN_C
 
 #endif /* prnetdb_h___ */
--- a/pr/include/prrng.h
+++ b/pr/include/prrng.h
@@ -11,59 +11,20 @@
  * NPL.
  * 
  * The Initial Developer of this code under the NPL is Netscape
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1999 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
-/*
-** Delete this section of the header after (if) agreement is reached to
-** provide the service suggested here. Move some parts of it, if
-** appropriate to platform specific implementation files.
-**
-** Proposal: Nothing in this header file should be construed as a
-** commitment on the part of the NSPR team, Netsacpe/AOL/Sun Alliance
-** et.al. to provide the API or function suggested in this header file.
-** This is a proposal, a draft, yadda. ... So, don't count on it.
-** lth. 29-Oct-1999
-**
-** --------------------------------------------------------------------
-**
-** Requirements, Discussion:
-**
-** Goal: foreach platform, find at least 160 bits of "good noise", that
-** is: from the platform itself, not extrapolated, stired, hashed,
-** xor'd, whatever, from a little available noise.
-**
-**
-** Required on the following platforms:
-**   MAC, Win9x, WinNT, Solaris, Linux (k: 2.2.x).
-** Best effort on: 
-**   AIX, HP-UX.
-** Not required on: 
-**   Tru65 Unix (Compaq)
-**
-** Notes: 
-** 
-** I presume it is legal to put this function on Mozilla.org,
-** that it is not regulated as "cryptographic 'munitions'". 
-**
-** Cartman says they need it 15-Jan-2000.
-**
-** --------------------------------------------------------------------
-*/
 
 /*
 ** prrng.h -- NSPR Random Number Generator
 ** 
-** 
-** 
-** 
 **
 ** lth. 29-Oct-1999.
 */
 
 #ifndef prrng_h___ 
 #define prrng_h___
 
 #include "prtypes.h"
@@ -108,18 +69,17 @@ PR_BEGIN_EXTERN_C
 **   Some platforms may block for up to a few seconds while they
 **   accumulate some noise. Busy machines generate lots of noise, but
 **   care is advised when using PR_GetRandomNoise() frequently in your
 **   application.
 **
 ** History:
 **   Parts of the model dependent implementation for PR_GetRandomNoise()
 **   were taken in whole or part from code previously in Netscape's NSS
-**   component. There is no Goddamned Goverenment Munitions is this
-**   code. Clinton: FOAD.
+**   component.
 **
 */
 NSPR_API(PRSize) PR_GetRandomNoise( 
     void    *buf,
     PRSize  size
 );
 
 PR_END_EXTERN_C
--- a/pr/include/prshm.h
+++ b/pr/include/prshm.h
@@ -108,16 +108,17 @@
 **
 ** lth. 18-Aug-1999.
 */
 
 #ifndef prshm_h___
 #define prshm_h___
 
 #include "prtypes.h"
+#include "prio.h"
 
 PR_BEGIN_EXTERN_C
 
 /*
 ** Declare opaque type PRSharedMemory.
 */
 typedef struct PRSharedMemory PRSharedMemory;
 
--- a/pr/include/prtpool.h
+++ b/pr/include/prtpool.h
@@ -17,70 +17,80 @@
  */
 
 #ifndef prtpool_h___
 #define prtpool_h___
 
 #include "prtypes.h"
 #include "prthread.h"
 #include "prio.h"
-#include "prerr.h"
 #include "prerror.h"
 
+/*
+ * NOTE:
+ *		THIS API IS A PRELIMINARY VERSION IN NSPR 4.0 AND IS SUBJECT TO
+ *		CHANGE
+ */
+
 PR_BEGIN_EXTERN_C
 
 typedef struct PRJobIoDesc {
     PRFileDesc *socket;
     PRErrorCode error;
     PRIntervalTime timeout;
 } PRJobIoDesc;
 
 typedef struct PRThreadPool PRThreadPool;
 typedef struct PRJob PRJob;
-typedef void (PR_CALLBACK *JobFn) (void *arg);
+typedef void (PR_CALLBACK *PRJobFn) (void *arg);
 
 /* Create thread pool */
-PR_EXTERN(PRThreadPool *)
+NSPR_API(PRThreadPool *)
 PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
-                          PRSize stacksize);
+                          PRUint32 stacksize);
 
 /* queue a job */
-PR_EXTERN(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable);
+NSPR_API(PRJob *)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable);
 
 /* queue a job, when a socket is readable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod,
-							JobFn fn, void * arg, PRBool joinable);
+							PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a socket is writeable */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod,
-								JobFn fn, void * arg, PRBool joinable);
+								PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a socket has a pending connection */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Accept(PRThreadPool *tpool, PRJobIoDesc *iod,
-									JobFn fn, void * arg, PRBool joinable);
+									PRJobFn fn, void * arg, PRBool joinable);
+
+/* queue a job, when the socket connection to addr succeeds or fails */
+NSPR_API(PRJob *)
+PR_QueueJob_Connect(PRThreadPool *tpool, PRJobIoDesc *iod,
+			const PRNetAddr *addr, PRJobFn fn, void * arg, PRBool joinable);
 
 /* queue a job, when a timer exipres */
-PR_EXTERN(PRJob *)
+NSPR_API(PRJob *)
 PR_QueueJob_Timer(PRThreadPool *tpool, PRIntervalTime timeout,
-								JobFn fn, void * arg, PRBool joinable);
+								PRJobFn fn, void * arg, PRBool joinable);
 /* cancel a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_CancelJob(PRJob *job);
 
 /* join a job */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_JoinJob(PRJob *job);
 
 /* shutdown pool */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_ShutdownThreadPool(PRThreadPool *tpool);
 
 /* join pool, wait for exit of all threads */
-PR_EXTERN(PRStatus)
+NSPR_API(PRStatus)
 PR_JoinThreadPool(PRThreadPool *tpool);
 
 PR_END_EXTERN_C
 
 #endif /* prtpool_h___ */
--- a/pr/include/prvrsion.h
+++ b/pr/include/prvrsion.h
@@ -69,19 +69,29 @@ typedef struct {
 /* on NT, restore the previous packing */
 #ifdef _WIN32
 #pragma pack(pop)
 #endif
 
 /*
  * All components must define an entrypoint named libVersionPoint which
  * is of type versionEntryPointType.
+ *
+ * For example, for a library named libfoo, we would have:
+ *
+ *   PRVersionDescription prVersionDescription_libfoo =
+ *   {
+ *       ...
+ *   };
+ *
+ *   PR_IMPLEMENT(const PRVersionDescription*) libVersionPoint(void)
+ *   {
+ *       return &prVersionDescription_libfoo;
+ *   }
  */
-NSPR_API(const PRVersionDescription *) libVersionPoint(void);
-
 typedef const PRVersionDescription *(*versionEntryPointType)(void);
 
 /* 
  * Where you declare your libVersionPoint, do it like this: 
  * PR_IMPLEMENT(const PRVersionDescription *) libVersionPoint(void) {
  *  fill it in...
  * }
  */
--- a/pr/src/Makefile
+++ b/pr/src/Makefile
@@ -136,30 +136,31 @@ OS_LIBS		= -lsocket -lc
 endif
 
 ifeq ($(OS_ARCH),NEWS-OS)
 OS_LIBS		= -lsocket -lnsl -lgen -lresolv
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 ifneq ($(OS_TARGET),WIN16)
-OS_LIBS		= wsock32.lib winmm.lib
+OS_LIBS		= advapi32.lib wsock32.lib winmm.lib
 endif
 endif
 
 #
 # Define platform-dependent OBJS
 #
 
 OBJS = \
     $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \
     threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \
@@ -222,20 +223,16 @@ OBJS += \
 	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
 endif
 
 endif
 
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
 ifeq ($(USE_CPLUS), 1)
 OBJS += \
 	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \
@@ -284,30 +281,32 @@ else
 ifeq ($(OS_TARGET), WIN95)
 OBJS +=	md/windows/$(OBJDIR)/w95io.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95sock.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95thred.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w95cv.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+	md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32rng.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32shm.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w95dllmain.$(OBJ_SUFFIX)
 else
 OBJS +=	md/windows/$(OBJDIR)/ntdllmn.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntio.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntgc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntthread.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntmisc.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/ntinrval.$(OBJ_SUFFIX) \
+	md/windows/$(OBJDIR)/ntsec.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/ntsem.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/win32_errors.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32ipcsem.$(OBJ_SUFFIX) \
 	md/windows/$(OBJDIR)/w32rng.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32shm.$(OBJ_SUFFIX)	\
 	md/windows/$(OBJDIR)/w32poll.$(OBJ_SUFFIX)
 endif
 endif
--- a/pr/src/Makefile.in
+++ b/pr/src/Makefile.in
@@ -157,16 +157,17 @@ endif # USE_AUTOCONF
 #
 
 OBJS = \
     $(OBJDIR)/prvrsion.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prfdcach.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmwait.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmapopt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/priometh.$(OBJ_SUFFIX) \
+    io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlayer.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prlog.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prmmap.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prpolevt.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prprf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prscanf.$(OBJ_SUFFIX) \
     io/$(OBJDIR)/prstdio.$(OBJ_SUFFIX) \
     threads/$(OBJDIR)/prcmon.$(OBJ_SUFFIX) \
@@ -224,20 +225,16 @@ OBJS += \
 	threads/combined/$(OBJDIR)/prucv.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prulock.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/prustack.$(OBJ_SUFFIX) \
 	threads/combined/$(OBJDIR)/pruthr.$(OBJ_SUFFIX)
 endif
 
 endif
 
-ifeq ($(USE_IPV6), 1)
-OBJS += io/$(OBJDIR)/pripv6.$(OBJ_SUFFIX)
-endif
-
 ifeq ($(USE_CPLUS), 1)
 OBJS += \
 	cplus/$(OBJDIR)/rcbase.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rccv.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcfileio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcinrval.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rcio.$(OBJ_SUFFIX) \
 	cplus/$(OBJDIR)/rclock.$(OBJ_SUFFIX) \
--- a/pr/src/io/Makefile
+++ b/pr/src/io/Makefile
@@ -27,16 +27,17 @@ ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 CSRCS = \
     prfdcach.c \
     prmwait.c \
     priometh.c \
+    pripv6.c \
 	prmapopt.c \
     prlayer.c \
     prlog.c \
 	prmmap.c \
     prpolevt.c \
 	prprf.c \
 	prscanf.c \
 	prstdio.c  \
@@ -46,20 +47,16 @@ ifndef USE_PTHREADS
     CSRCS += \
 	    prdir.c \
 	    prfile.c \
 	    prio.c \
 	    prsocket.c \
 	    $(NULL)
 endif
 
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
 TARGETS	= $(OBJS)
 
 INCLUDES = -I$(DIST)/include -I$(MOD_DEPTH)/pr/include -I$(MOD_DEPTH)/pr/include/private
 
 DEFINES     += -D_NSPR_BUILD_
 
 include $(MOD_DEPTH)/config/rules.mk
 
--- a/pr/src/io/Makefile.in
+++ b/pr/src/io/Makefile.in
@@ -32,16 +32,17 @@ ifeq ($(OS_RELEASE),4.1.3_U1)
 OPTIMIZER =
 endif
 endif
 
 CSRCS = \
     prfdcach.c \
     prmwait.c \
     priometh.c \
+    pripv6.c \
 	prmapopt.c \
     prlayer.c \
     prlog.c \
 	prmmap.c \
     prpolevt.c \
 	prprf.c \
 	prscanf.c \
 	prstdio.c  \
@@ -51,20 +52,16 @@ ifndef USE_PTHREADS
     CSRCS += \
 	    prdir.c \
 	    prfile.c \
 	    prio.c \
 	    prsocket.c \
 	    $(NULL)
 endif
 
-ifdef USE_IPV6
-CSRCS += pripv6.c
-endif
-
 TARGETS	= $(OBJS)
 
 INCLUDES = -I$(DIST)/include -I$(topsrcdir)/pr/include -I$(topsrcdir)/pr/include/private
 
 DEFINES	+= -D_NSPR_BUILD_
 
 include $(topsrcdir)/config/rules.mk
 
--- a/pr/src/io/prdir.c
+++ b/pr/src/io/prdir.c
@@ -65,16 +65,28 @@ PRInt32 rv;
 
 	rv = _PR_MD_MKDIR(name, mode);
 	if (rv < 0) {
 		return PR_FAILURE;
 	} else
 		return PR_SUCCESS;
 }
 
+PR_IMPLEMENT(PRStatus) PR_MakeDir(const char *name, PRIntn mode)
+{
+PRInt32 rv;
+
+	if (!_pr_initialized) _PR_ImplicitInitialization();
+	rv = _PR_MD_MAKE_DIR(name, mode);
+	if (rv < 0) {
+		return PR_FAILURE;
+	} else
+		return PR_SUCCESS;
+}
+
 PR_IMPLEMENT(PRStatus) PR_RmDir(const char *name)
 {
 PRInt32 rv;
 
 	rv = _PR_MD_RMDIR(name);
 	if (rv < 0) {
 		return PR_FAILURE;
 	} else
--- a/pr/src/io/prfdcach.c
+++ b/pr/src/io/prfdcach.c
@@ -110,24 +110,24 @@ PRFileDesc *_PR_Getfd()
 
         } while (NULL == fd);  /* then go around and allocate a new one */
     }
 
 finished:
     fd->dtor = NULL;
     fd->lower = fd->higher = NULL;
     fd->identity = PR_NSPR_IO_LAYER;
-    memset(fd->secret, 0, PRFILEPRIVATE_SIZE);
+    memset(fd->secret, 0, sizeof(PRFilePrivate));
     return fd;
 
 allocate:
     fd = PR_NEW(PRFileDesc);
     if (NULL != fd)
     {
-        fd->secret = (PRFilePrivate *) PR_MALLOC(PRFILEPRIVATE_SIZE);
+        fd->secret = PR_NEW(PRFilePrivate);
         if (NULL == fd->secret) PR_DELETE(fd);
     }
     if (NULL != fd) goto finished;
     else return NULL;
 
 }  /* _PR_Getfd */
 
 /*
--- a/pr/src/io/prfile.c
+++ b/pr/src/io/prfile.c
@@ -263,18 +263,18 @@ static PRIOMethods _pr_fileMethods = {
     (PRSendFN)_PR_InvalidInt,		
     (PRRecvfromFN)_PR_InvalidInt,	
     (PRSendtoFN)_PR_InvalidInt,		
     FilePoll,         
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,	
     (PRGetpeernameFN)_PR_InvalidStatus,	
-    (PRGetsockoptFN)_PR_InvalidStatus,	
-    (PRSetsockoptFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
     (PRGetsocketoptionFN)_PR_InvalidStatus,	
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -307,18 +307,18 @@ static PRIOMethods _pr_pipeMethods = {
     (PRSendFN)_PR_InvalidInt,		
     (PRRecvfromFN)_PR_InvalidInt,	
     (PRSendtoFN)_PR_InvalidInt,		
     FilePoll,         
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,	
     (PRGetpeernameFN)_PR_InvalidStatus,	
-    (PRGetsockoptFN)_PR_InvalidStatus,	
-    (PRSetsockoptFN)_PR_InvalidStatus,	
+    (PRReservedFN)_PR_InvalidInt,	
+    (PRReservedFN)_PR_InvalidInt,	
     (PRGetsocketoptionFN)_PR_InvalidStatus,	
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -343,16 +343,36 @@ PR_IMPLEMENT(PRFileDesc*) PR_Open(const 
         fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
         if (!fd) {
             (void) _PR_MD_CLOSE_FILE(osfd);
         }
     }
     return fd;
 }
 
+PR_IMPLEMENT(PRFileDesc*) PR_OpenFile(
+    const char *name, PRIntn flags, PRIntn mode)
+{
+    PRInt32 osfd;
+    PRFileDesc *fd = 0;
+
+    if (!_pr_initialized) _PR_ImplicitInitialization();
+
+    /* Map pr open flags and mode to os specific flags */
+
+    osfd = _PR_MD_OPEN_FILE(name, flags, mode);
+    if (osfd != -1) {
+        fd = PR_AllocFileDesc(osfd, &_pr_fileMethods);
+        if (!fd) {
+            (void) _PR_MD_CLOSE_FILE(osfd);
+        }
+    }
+    return fd;
+}
+
 PRInt32 PR_GetSysfdTableMax(void)
 {
 #if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX)
     struct rlimit rlim;
 
     if ( getrlimit(RLIMIT_NOFILE, &rlim) < 0) {
        /* XXX need to call PR_SetError() */
        return -1;
--- a/pr/src/io/priometh.c
+++ b/pr/src/io/priometh.c
@@ -43,18 +43,18 @@ PRIOMethods _pr_faulty_methods = {
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
     (PRPollFN)_PR_InvalidInt16,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt
@@ -242,36 +242,16 @@ PR_IMPLEMENT(PRStatus) PR_GetSockName(PR
 	return((fd->methods->getsockname)(fd,addr));
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetPeerName(PRFileDesc *fd, PRNetAddr *addr)
 {
 	return((fd->methods->getpeername)(fd,addr));
 }
 
-PR_IMPLEMENT(PRStatus) PR_GetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_GetSockOpt()", "PR_GetSocketOption()");
-#endif
-	return((fd->methods->getsockopt)(fd, optname, optval, optlen));
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_SetSockOpt()", "PR_SetSocketOption()");
-#endif
-	return((fd->methods->setsockopt)(fd, optname, optval, optlen));
-}
-
 PR_IMPLEMENT(PRStatus) PR_GetSocketOption(
     PRFileDesc *fd, PRSocketOptionData *data)
 {
 	return((fd->methods->getsocketoption)(fd, data));
 }
 
 PR_IMPLEMENT(PRStatus) PR_SetSocketOption(
     PRFileDesc *fd, const PRSocketOptionData *data)
--- a/pr/src/io/pripv6.c
+++ b/pr/src/io/pripv6.c
@@ -15,12 +15,346 @@
  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
 /*
 ** File:        pripv6.c
 ** Description: Support for various functions unique to IPv6
 */
+#include "primpl.h"
+#include <string.h>
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+
+static PRIOMethods ipv6_to_v4_tcpMethods;
+static PRIOMethods ipv6_to_v4_udpMethods;
+static PRDescIdentity _pr_ipv6_to_ipv4_id;
+extern PRBool IsValidNetAddr(const PRNetAddr *addr);
+extern PRIPv6Addr _pr_in6addr_any;
+extern PRIPv6Addr _pr_in6addr_loopback;
+
+/*
+ * convert an IPv4-mapped IPv6 addr to an IPv4 addr
+ */
+static void _PR_ConvertToIpv4NetAddr(const PRNetAddr *src_v6addr,
+											PRNetAddr *dst_v4addr)
+{
+const PRUint8 *srcp;
+
+	PR_ASSERT(PR_AF_INET6 == src_v6addr->ipv6.family);
+
+	if (PR_IsNetAddrType(src_v6addr, PR_IpAddrV4Mapped)) {
+		srcp = src_v6addr->ipv6.ip.pr_s6_addr;
+		memcpy((char *) &dst_v4addr->inet.ip, srcp + 12, 4);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrAny)) {
+        dst_v4addr->inet.ip = htonl(INADDR_ANY);
+    } else if (PR_IsNetAddrType(src_v6addr, PR_IpAddrLoopback)) {
+        dst_v4addr->inet.ip = htonl(INADDR_LOOPBACK);
+    }
+	dst_v4addr->inet.family = PR_AF_INET;
+	dst_v4addr->inet.port = src_v6addr->ipv6.port;
+}
+
+/*
+ * convert an IPv4 addr to an IPv4-mapped IPv6 addr
+ */
+static void _PR_ConvertToIpv6NetAddr(const PRNetAddr *src_v4addr,
+                                            PRNetAddr *dst_v6addr)
+{
+PRUint8 *dstp;
+
+	PR_ASSERT(PR_AF_INET == src_v4addr->inet.family);
+	dst_v6addr->ipv6.family = PR_AF_INET6;
+	dst_v6addr->ipv6.port = src_v4addr->inet.port;
+
+ 	if (htonl(INADDR_ANY) == src_v4addr->inet.ip) {
+		dst_v6addr->ipv6.ip = _pr_in6addr_any;
+	} else {
+		dstp = dst_v6addr->ipv6.ip.pr_s6_addr;
+		memset(dstp, 0, 10);
+		memset(dstp + 10, 0xff, 2);
+		memcpy(dstp + 12,(char *) &src_v4addr->inet.ip, 4);
+	}
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketBind(PRFileDesc *fd,
+								const PRNetAddr *addr)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+	PRFileDesc *lo = fd->lower;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+    			PR_IsNetAddrType(addr, PR_IpAddrAny)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return((lo->methods->bind)(lo,tmp_addrp));
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketConnect(
+    PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+	return (fd->lower->methods->connect)(fd->lower, tmp_addrp, timeout);
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketSendTo(
+    PRFileDesc *fd, const void *buf, PRInt32 amount,
+    PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	const PRNetAddr *tmp_addrp;
+
+	if (PR_AF_INET6 != addr->raw.family) {
+        PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
+		return PR_FAILURE;
+	}
+	if (PR_IsNetAddrType(addr, PR_IpAddrV4Mapped) ||
+			PR_IsNetAddrType(addr, PR_IpAddrLoopback)) {
+		_PR_ConvertToIpv4NetAddr(addr, &tmp_ipv4addr);
+		tmp_addrp = &tmp_ipv4addr;
+	} else {
+        PR_SetError(PR_NETWORK_UNREACHABLE_ERROR, 0);
+		return PR_FAILURE;
+	}
+    return (fd->lower->methods->sendto)(
+        fd->lower, buf, amount, flags, tmp_addrp, timeout);
+}
+
+static PRFileDesc* PR_CALLBACK Ipv6ToIpv4SocketAccept (
+    PRFileDesc *fd, PRNetAddr *addr, PRIntervalTime timeout)
+{
+    PRStatus rv;
+    PRFileDesc *newfd;
+    PRFileDesc *newstack;
+	PRNetAddr tmp_ipv4addr;
+
+    PR_ASSERT(fd != NULL);
+    PR_ASSERT(fd->lower != NULL);
+
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return NULL;
+    }
+    *newstack = *fd;  /* make a copy of the accepting layer */
+
+    newfd = (fd->lower->methods->accept)(fd->lower, &tmp_ipv4addr, timeout);
+    if (NULL == newfd)
+    {
+        PR_DELETE(newstack);
+        return NULL;
+    }
+	_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, addr);
+
+    rv = PR_PushIOLayer(newfd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return newfd;  /* that's it */
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketAcceptRead(PRFileDesc *sd,
+			PRFileDesc **nd, PRNetAddr **ipv6_raddr, void *buf, PRInt32 amount,
+							PRIntervalTime timeout)
+{
+    PRInt32 nbytes;
+    PRStatus rv;
+	PRNetAddr tmp_ipv4addr;
+    PRFileDesc *newstack;
+
+    PR_ASSERT(sd != NULL);
+    PR_ASSERT(sd->lower != NULL);
 
-/* pripv6.c */
+    newstack = PR_NEW(PRFileDesc);
+    if (NULL == newstack)
+    {
+        PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
+        return -1;
+    }
+    *newstack = *sd;  /* make a copy of the accepting layer */
+
+    nbytes = sd->lower->methods->acceptread(
+        sd->lower, nd, ipv6_raddr, buf, amount, timeout);
+    if (-1 == nbytes)
+    {
+        PR_DELETE(newstack);
+        return nbytes;
+    }
+	tmp_ipv4addr = **ipv6_raddr;	/* copy */
+	_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, *ipv6_raddr);
+
+    /* this PR_PushIOLayer call cannot fail */
+    rv = PR_PushIOLayer(*nd, PR_TOP_IO_LAYER, newstack);
+    PR_ASSERT(PR_SUCCESS == rv);
+    return nbytes;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRStatus PR_CALLBACK Ipv6ToIpv4SocketGetPeerName(PRFileDesc *fd,
+										PRNetAddr *ipv6addr)
+{
+	PRStatus result;
+	PRNetAddr tmp_ipv4addr;
+
+	result = (fd->lower->methods->getsockname)(fd->lower, &tmp_ipv4addr);
+	if (PR_SUCCESS == result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+static PRInt32 PR_CALLBACK Ipv6ToIpv4SocketRecvFrom(PRFileDesc *fd, void *buf,
+			PRInt32 amount, PRIntn flags, PRNetAddr *ipv6addr,
+				PRIntervalTime timeout)
+{
+	PRNetAddr tmp_ipv4addr;
+	PRInt32 result;
+
+    result = (fd->lower->methods->recvfrom)(
+        fd->lower, buf, amount, flags, &tmp_ipv4addr, timeout);
+	if (-1 != result) {
+		_PR_ConvertToIpv6NetAddr(&tmp_ipv4addr, ipv6addr);
+		PR_ASSERT(IsValidNetAddr(ipv6addr) == PR_TRUE);
+	}
+	return result;
+}
+
+#if defined(_PR_INET6_PROBE)
+PRBool _pr_ipv6_is_present;
+PR_EXTERN(PRBool) _pr_test_ipv6_socket();
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+void *_pr_getipnodebyname_fp;
+void *_pr_getipnodebyaddr_fp;
+void *_pr_freehostent_fp;
+#endif
+#endif
+
+PRStatus _pr_init_ipv6()
+{
+    const PRIOMethods *stubMethods;
+
+#if defined(_PR_INET6_PROBE)
 
+#if !defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+	PRLibrary *lib;	
+	_pr_getipnodebyname_fp = PR_FindSymbolAndLibrary("getipnodebyname", &lib);
+	if (NULL != _pr_getipnodebyname_fp) {
+		_pr_freehostent_fp = PR_FindSymbol(lib, "freehostent");
+		if (NULL != _pr_freehostent_fp) {
+			_pr_getipnodebyaddr_fp = PR_FindSymbol(lib, "getipnodebyaddr");
+			if (NULL != _pr_getipnodebyaddr_fp)
+				_pr_ipv6_is_present = PR_TRUE;
+			else
+				_pr_ipv6_is_present = PR_FALSE;
+		} else
+			_pr_ipv6_is_present = PR_FALSE;
+		(void)PR_UnloadLibrary(lib);
+	} else
+		_pr_ipv6_is_present = PR_FALSE;
+	if (PR_TRUE == _pr_ipv6_is_present)
+#endif
+	
+	_pr_ipv6_is_present = _pr_test_ipv6_socket();
+	if (PR_TRUE == _pr_ipv6_is_present)
+			return PR_SUCCESS;
+#endif
+
+    _pr_ipv6_to_ipv4_id = PR_GetUniqueIdentity("Ipv6_to_Ipv4 layer");
+    PR_ASSERT(PR_INVALID_IO_LAYER != _pr_ipv6_to_ipv4_id);
+
+	stubMethods = PR_GetDefaultIOMethods();
+
+	ipv6_to_v4_tcpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_tcpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_tcpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_tcpMethods.accept = Ipv6ToIpv4SocketAccept;
+	ipv6_to_v4_tcpMethods.acceptread = Ipv6ToIpv4SocketAcceptRead;
+	ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	ipv6_to_v4_udpMethods = *stubMethods;  /* first get the entire batch */
+	/* then override the ones we care about */
+	ipv6_to_v4_udpMethods.connect = Ipv6ToIpv4SocketConnect;
+	ipv6_to_v4_udpMethods.bind = Ipv6ToIpv4SocketBind;
+	ipv6_to_v4_udpMethods.sendto = Ipv6ToIpv4SocketSendTo;
+	ipv6_to_v4_udpMethods.recvfrom = Ipv6ToIpv4SocketRecvFrom;
+	ipv6_to_v4_tcpMethods.getsockname = Ipv6ToIpv4SocketGetName;
+	ipv6_to_v4_tcpMethods.getpeername = Ipv6ToIpv4SocketGetPeerName;
+/*
+	ipv6_to_v4_tcpMethods.getsocketoption = Ipv6ToIpv4GetSocketOption;
+	ipv6_to_v4_tcpMethods.setsocketoption = Ipv6ToIpv4SetSocketOption;
+*/
+	return PR_SUCCESS;
+}
+
+PR_IMPLEMENT(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd)
+{
+	PRFileDesc *ipv6_fd = NULL;
+
+	/*
+	 * For platforms with no support for IPv6 
+	 * create layered socket for IPv4-mapped IPv6 addresses
+	 */
+	if (fd->methods->file_type == PR_DESC_SOCKET_TCP)
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_tcpMethods);
+	else
+		ipv6_fd = PR_CreateIOLayerStub(_pr_ipv6_to_ipv4_id,
+									&ipv6_to_v4_udpMethods);
+	if (NULL == ipv6_fd) {
+		goto errorExit;
+	} 
+	ipv6_fd->secret = NULL;
+
+	if (PR_PushIOLayer(fd, PR_TOP_IO_LAYER, ipv6_fd) == PR_FAILURE) {
+		goto errorExit;
+	}
+
+	return PR_SUCCESS;
+errorExit:
+
+	if (ipv6_fd)
+		ipv6_fd->dtor(ipv6_fd);
+	return PR_FAILURE;
+}
+
+#endif /* !defined(_PR_INET6) || defined(_PR_INET6_PROBE) */
--- a/pr/src/io/prlayer.c
+++ b/pr/src/io/prlayer.c
@@ -314,34 +314,16 @@ static PRStatus PR_CALLBACK pl_DefGetsoc
 static PRStatus PR_CALLBACK pl_DefGetpeername (PRFileDesc *fd, PRNetAddr *addr)
 {
     PR_ASSERT(fd != NULL);
     PR_ASSERT(fd->lower != NULL);
 
     return (fd->lower->methods->getpeername)(fd->lower, addr);
 }
 
-static PRStatus PR_CALLBACK pl_DefGetsockopt (
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-    PR_ASSERT(fd != NULL);
-    PR_ASSERT(fd->lower != NULL);
-
-    return (fd->lower->methods->getsockopt)(fd->lower, optname, optval, optlen);
-}
-
-static PRStatus PR_CALLBACK pl_DefSetsockopt (
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-    PR_ASSERT(fd != NULL);
-    PR_ASSERT(fd->lower != NULL);
-
-    return (fd->lower->methods->setsockopt)(fd->lower, optname, optval, optlen);
-}
-
 static PRStatus PR_CALLBACK pl_DefGetsocketoption (
     PRFileDesc *fd, PRSocketOptionData *data)
 {
     PR_ASSERT(fd != NULL);
     PR_ASSERT(fd->lower != NULL);
 
     return (fd->lower->methods->getsocketoption)(fd->lower, data);
 }
@@ -389,18 +371,18 @@ static PRIOMethods pl_methods = {
     pl_DefSend,
     pl_DefRecvfrom,
     pl_DefSendto,
     pl_DefPoll,
     pl_DefAcceptread,
     pl_DefTransmitfile,
     pl_DefGetsockname,
     pl_DefGetpeername,
-    pl_DefGetsockopt,
-    pl_DefSetsockopt,
+    (PRReservedFN)_PR_InvalidInt,
+    (PRReservedFN)_PR_InvalidInt,
     pl_DefGetsocketoption,
     pl_DefSetsocketoption,
     pl_DefSendfile,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt,
     (PRReservedFN)_PR_InvalidInt
--- a/pr/src/io/prpolevt.c
+++ b/pr/src/io/prpolevt.c
@@ -164,18 +164,18 @@ static PRIOMethods _pr_polevt_methods = 
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
     _pr_PolEvtPoll,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
--- a/pr/src/io/prsocket.c
+++ b/pr/src/io/prsocket.c
@@ -20,26 +20,24 @@
 
 #include <string.h>
 
 /************************************************************************/
 
 /* These two functions are only used in assertions. */
 #if defined(DEBUG)
 
-static PRBool IsValidNetAddr(const PRNetAddr *addr)
+PRBool IsValidNetAddr(const PRNetAddr *addr)
 {
     if ((addr != NULL)
 #ifdef XP_UNIX
-	    && (addr->raw.family != AF_UNIX)
+	    && (addr->raw.family != PR_AF_LOCAL)
 #endif
-#ifdef _PR_INET6
-	    && (addr->raw.family != AF_INET6)
-#endif
-	    && (addr->raw.family != AF_INET)) {
+	    && (addr->raw.family != PR_AF_INET6)
+	    && (addr->raw.family != PR_AF_INET)) {
         return PR_FALSE;
     }
     return PR_TRUE;
 }
 
 static PRBool IsValidNetAddrLen(const PRNetAddr *addr, PRInt32 addr_len)
 {
     /*
@@ -223,25 +221,36 @@ PR_IMPLEMENT(PRStatus) PR_DestroySocketP
     _PR_Putfd(fd);
     return PR_SUCCESS;
 }  /* PR_DestroySocketPollFd */
 
 static PRStatus PR_CALLBACK SocketConnect(
     PRFileDesc *fd, const PRNetAddr *addr, PRIntervalTime timeout)
 {
 	PRInt32 rv;    /* Return value of _PR_MD_CONNECT */
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 	PRThread *me = _PR_MD_CURRENT_THREAD();
 
 	if (_PR_PENDING_INTERRUPT(me)) {
 		me->flags &= ~_PR_INTERRUPT;
 		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 		return PR_FAILURE;
 	}
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
 
-	rv = _PR_MD_CONNECT(fd, addr, PR_NETADDR_SIZE(addr), timeout);
+	rv = _PR_MD_CONNECT(fd, addrp, PR_NETADDR_SIZE(addr), timeout);
 	PR_LOG(_pr_io_lm, PR_LOG_MAX, ("connect -> %d", rv));
 	if (rv == 0)
 		return PR_SUCCESS;
 	else
 		return PR_FAILURE;
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetConnectStatus(const PRPollDesc *pd)
@@ -409,16 +418,20 @@ PRIntervalTime timeout)
 	 * (which maps to _MD_makenonblock, see macsockotpt.c)
 	 * installs the async notifier routine needed to make blocking
 	 * I/O work properly.
 	 */
 #if !defined(SOLARIS) && !defined(IRIX) && !defined(WINNT)
 	_PR_MD_MAKE_NONBLOCK(fd2);
 #endif
 
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, al) == PR_TRUE);
 
 	return fd2;
 }
 
 #ifdef WINNT
 PR_IMPLEMENT(PRFileDesc*) PR_NTFast_Accept(PRFileDesc *fd, PRNetAddr *addr,
@@ -453,39 +466,54 @@ PRIntervalTime timeout)
 	if (!fd2) {
 		_PR_MD_CLOSE_SOCKET(osfd);
 	} else {
 		fd2->secret->nonblocking = fd->secret->nonblocking;
 		fd2->secret->md.io_model_committed = PR_TRUE;
 	        PR_ASSERT(al == PR_NETADDR_SIZE(addr));
         	fd2->secret->md.accepted_socket = PR_TRUE;
         	memcpy(&fd2->secret->md.peer_addr, addr, al);
+#ifdef _PR_INET6
+		if (AF_INET6 == addr->raw.family)
+        	addr->raw.family = PR_AF_INET6;
+#endif
 	}
 	return fd2;
 }
 #endif /* WINNT */
 
 
 static PRStatus PR_CALLBACK SocketBind(PRFileDesc *fd, const PRNetAddr *addr)
 {
 	PRInt32 result;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 
 #ifdef XP_UNIX
 	if (addr->raw.family == AF_UNIX) {
 		/* Disallow relative pathnames */
 		if (addr->local.path[0] != '/') {
 			PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 			return PR_FAILURE;
 		}
 	}
 #endif /* XP_UNIX */
 
-	result = _PR_MD_BIND(fd, addr, PR_NETADDR_SIZE(addr));
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
+	result = _PR_MD_BIND(fd, addrp, PR_NETADDR_SIZE(addr));
 	if (result < 0) {
 		return PR_FAILURE;
 	}
 	return PR_SUCCESS;
 }
 
 static PRStatus PR_CALLBACK SocketListen(PRFileDesc *fd, PRIntn backlog)
 {
@@ -625,34 +653,45 @@ static PRStatus PR_CALLBACK SocketSync(P
 	return PR_SUCCESS;
 }
 
 static PRInt32 PR_CALLBACK SocketSendTo(
     PRFileDesc *fd, const void *buf, PRInt32 amount,
     PRIntn flags, const PRNetAddr *addr, PRIntervalTime timeout)
 {
 	PRInt32 temp, count;
+    const PRNetAddr *addrp = addr;
+#if defined(_PR_INET6)
+	PRNetAddr addrCopy;
+#endif
 	PRThread *me = _PR_MD_CURRENT_THREAD();
 
 	if (_PR_PENDING_INTERRUPT(me)) {
 		me->flags &= ~_PR_INTERRUPT;
 		PR_SetError(PR_PENDING_INTERRUPT_ERROR, 0);
 		return -1;
 	}
 	if (_PR_IO_PENDING(me)) {
 		PR_SetError(PR_IO_PENDING_ERROR, 0);
 		return -1;
 	}
 
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
+#if defined(_PR_INET6)
+	if (addr->raw.family == PR_AF_INET6) {
+		addrCopy = *addr;
+		addrCopy.raw.family = AF_INET6;
+		addrp = &addrCopy;
+	}
+#endif
 
 	count = 0;
 	while (amount > 0) {
 		temp = _PR_MD_SENDTO(fd, buf, amount, flags,
-		    addr, PR_NETADDR_SIZE(addr), timeout);
+		    addrp, PR_NETADDR_SIZE(addr), timeout);
 		if (temp < 0) {
 					count = -1;
 					break;
 				}
 		count += temp;
 		if (fd->secret->nonblocking) {
 			break;
 		}
@@ -676,16 +715,20 @@ PRIntn flags, PRNetAddr *addr, PRInterva
 	}
 	if (_PR_IO_PENDING(me)) {
 		PR_SetError(PR_IO_PENDING_ERROR, 0);
 		return -1;
 	}
 
 	al = sizeof(PRNetAddr);
 	rv = _PR_MD_RECVFROM(fd, buf, amount, flags, addr, &al, timeout);
+#ifdef _PR_INET6
+	if (addr && (AF_INET6 == addr->raw.family))
+        addr->raw.family = PR_AF_INET6;
+#endif
 	return rv;
 }
 
 static PRInt32 PR_CALLBACK SocketAcceptRead(PRFileDesc *sd, PRFileDesc **nd, 
 PRNetAddr **raddr, void *buf, PRInt32 amount,
 PRIntervalTime timeout)
 {
 	PRInt32 rv;
@@ -725,16 +768,20 @@ PRIntervalTime timeout)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	}
 #else
 	rv = _PR_EmulateAcceptRead(sd, nd, raddr, buf, amount, timeout);
 #endif
 	return rv;
 }
@@ -774,16 +821,20 @@ PRIntervalTime timeout)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	return rv;
 }
 
 PR_IMPLEMENT(PRInt32) PR_NTFast_AcceptRead_WithTimeoutCallback(
 PRFileDesc *sd, PRFileDesc **nd, 
 PRNetAddr **raddr, void *buf, PRInt32 amount,
@@ -821,16 +872,20 @@ void *callbackArg)
 			_PR_MD_CLOSE_SOCKET(newSock);
 			/* PR_AllocFileDesc() has invoked PR_SetError(). */
 			rv = -1;
 		} else {
 			(*nd)->secret->md.io_model_committed = PR_TRUE;
 			(*nd)->secret->md.accepted_socket = PR_TRUE;
 			memcpy(&(*nd)->secret->md.peer_addr, *raddr,
 				PR_NETADDR_SIZE(*raddr));
+#ifdef _PR_INET6
+			if (AF_INET6 == *raddr->raw.family)
+        		*raddr->raw.family = PR_AF_INET6;
+#endif
 		}
 	}
 	return rv;
 }
 #endif /* WINNT */
 
 #ifdef WINNT
 PR_IMPLEMENT(void)
@@ -905,146 +960,44 @@ static PRStatus PR_CALLBACK SocketGetNam
 	PRInt32 result;
 	PRUint32 addrlen;
 
 	addrlen = sizeof(PRNetAddr);
 	result = _PR_MD_GETSOCKNAME(fd, addr, &addrlen);
 	if (result < 0) {
 		return PR_FAILURE;
 	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
 	return PR_SUCCESS;
 }
 
 static PRStatus PR_CALLBACK SocketGetPeerName(PRFileDesc *fd, PRNetAddr *addr)
 {
 	PRInt32 result;
 	PRUint32 addrlen;
 
 	addrlen = sizeof(PRNetAddr);
 	result = _PR_MD_GETPEERNAME(fd, addr, &addrlen);
 	if (result < 0) {
 		return PR_FAILURE;
 	}
+#ifdef _PR_INET6
+	if (AF_INET6 == addr->raw.family)
+        addr->raw.family = PR_AF_INET6;
+#endif
 	PR_ASSERT(IsValidNetAddr(addr) == PR_TRUE);
 	PR_ASSERT(IsValidNetAddrLen(addr, addrlen) == PR_TRUE);
 	return PR_SUCCESS;
 }
 
-static PRStatus PR_CALLBACK SocketGetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, void* optval, PRInt32* optlen)
-{
-    PRInt32 level, name;
-    PRStatus rv;
-
-    /*
-     * PR_SockOpt_Nonblocking is a special case that does not
-     * translate to a getsockopt() call
-     */
-    if (PR_SockOpt_Nonblocking == optname)
-    {
-        PR_ASSERT(sizeof(PRIntn) <= *optlen);
-        *((PRIntn *) optval) = (PRIntn) fd->secret->nonblocking;
-        *optlen = sizeof(PRIntn);
-        return PR_SUCCESS;
-    }
-
-    rv = _PR_MapOptionName(optname, &level, &name);
-    if (PR_SUCCESS == rv)
-    {
-        if (PR_SockOpt_Linger == optname)
-        {
-#if !defined(XP_BEOS)
-            struct linger linger;
-            PRInt32 len = sizeof(linger);
-            rv = _PR_MD_GETSOCKOPT(
-                fd, level, name, (char *) &linger, &len);
-            if (PR_SUCCESS == rv)
-            {
-                ((PRLinger*)(optval))->polarity = linger.l_onoff
-                    ? PR_TRUE : PR_FALSE;
-                ((PRLinger*)(optval))->linger = PR_SecondsToInterval(
-                    linger.l_linger);
-                *optlen = sizeof(PRLinger);
-            }
-#else
-            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
-            return PR_FAILURE;
-#endif
-        }
-        else
-        {
-            rv = _PR_MD_GETSOCKOPT(
-                fd, level, name, (char*)optval, optlen);
-        }
-    }
-    return rv;
-}
-
-static PRStatus PR_CALLBACK SocketSetSockOpt(
-    PRFileDesc *fd, PRSockOption optname, const void* optval, PRInt32 optlen)
-{
-	PRInt32 level, name;
-    PRStatus rv;
-
-    /*
-     * PR_SockOpt_Nonblocking is a special case that does not
-     * translate to a setsockopt call.
-     */
-    if (PR_SockOpt_Nonblocking == optname)
-    {
-        PRBool fNonblocking = *((PRIntn *) optval) ? PR_TRUE : PR_FALSE;
-        PR_ASSERT(sizeof(PRIntn) == optlen);
-#ifdef WINNT
-        PR_ASSERT((fd->secret->md.io_model_committed == PR_FALSE)
-            || (fd->secret->nonblocking == fNonblocking));
-        if (fd->secret->md.io_model_committed
-            && (fd->secret->nonblocking != fNonblocking))
-        {
-            /*
-             * On NT, once we have associated a socket with the io
-             * completion port, we can't disassociate it.  So we
-             * can't change the nonblocking option of the socket
-             * afterwards.
-             */
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            return PR_FAILURE;
-        }
-#endif
-        fd->secret->nonblocking = fNonblocking;
-        return PR_SUCCESS;
-    }
-
-    rv = _PR_MapOptionName(optname, &level, &name);
-    if (PR_SUCCESS == rv)
-    {
-        if (PR_SockOpt_Linger == optname)
-        {
-#if !defined(XP_BEOS)
-            struct linger linger;
-            linger.l_onoff = ((PRLinger*)(optval))->polarity ? 1 : 0;
-            linger.l_linger = PR_IntervalToSeconds(
-                ((PRLinger*)(optval))->linger);
-            rv = _PR_MD_SETSOCKOPT(
-                fd, level, name, (char *) &linger, sizeof(linger));
-#else
-            PR_SetError( PR_NOT_IMPLEMENTED_ERROR, 0 );
-            return PR_FAILURE;
-#endif
-        }
-        else
-        {
-            rv = _PR_MD_SETSOCKOPT(
-                fd, level, name, (const char*)optval, optlen);
-        }
-    }
-    return rv;
-}
-
 static PRInt16 PR_CALLBACK SocketPoll(
     PRFileDesc *fd, PRInt16 in_flags, PRInt16 *out_flags)
 {
 #ifdef XP_MAC
 #pragma unused( fd, in_flags )
 #endif
     *out_flags = 0;
     return in_flags;
@@ -1072,18 +1025,18 @@ static PRIOMethods tcpMethods = {
 	SocketSend,
 	(PRRecvfromFN)_PR_InvalidInt,
 	(PRSendtoFN)_PR_InvalidInt,
 	SocketPoll,
 	SocketAcceptRead,
 	SocketTransmitFile,
 	SocketGetName,
 	SocketGetPeerName,
-	SocketGetSockOpt,
-	SocketSetSockOpt,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
 	_PR_SocketGetSocketOption,
 	_PR_SocketSetSocketOption,
     SocketSendFile, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1111,18 +1064,18 @@ static PRIOMethods udpMethods = {
 	SocketSend,
 	SocketRecvFrom,
 	SocketSendTo,
 	SocketPoll,
 	(PRAcceptreadFN)_PR_InvalidInt,
 	(PRTransmitfileFN)_PR_InvalidInt,
 	SocketGetName,
 	SocketGetPeerName,
-	SocketGetSockOpt,
-	SocketSetSockOpt,
+	(PRReservedFN)_PR_InvalidInt,
+	(PRReservedFN)_PR_InvalidInt,
 	_PR_SocketGetSocketOption,
 	_PR_SocketSetSocketOption,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1151,18 +1104,18 @@ static PRIOMethods socketpollfdMethods =
     (PRSendFN)_PR_InvalidInt,        
     (PRRecvfromFN)_PR_InvalidInt,    
     (PRSendtoFN)_PR_InvalidInt,        
 	SocketPoll,
     (PRAcceptreadFN)_PR_InvalidInt,   
     (PRTransmitfileFN)_PR_InvalidInt, 
     (PRGetsocknameFN)_PR_InvalidStatus,    
     (PRGetpeernameFN)_PR_InvalidStatus,    
-    (PRGetsockoptFN)_PR_InvalidStatus,    
-    (PRSetsockoptFN)_PR_InvalidStatus,    
+    (PRReservedFN)_PR_InvalidInt,    
+    (PRReservedFN)_PR_InvalidInt,    
     (PRGetsocketoptionFN)_PR_InvalidStatus,
     (PRSetsocketoptionFN)_PR_InvalidStatus,
     (PRSendfileFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt, 
     (PRReservedFN)_PR_InvalidInt
@@ -1178,73 +1131,117 @@ PR_IMPLEMENT(const PRIOMethods*) PR_GetU
 	return &udpMethods;
 }
 
 static const PRIOMethods* PR_GetSocketPollFdMethods()
 {
     return &socketpollfdMethods;
 }  /* PR_GetSocketPollFdMethods */
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+PR_EXTERN(PRStatus) _pr_push_ipv6toipv4_layer(PRFileDesc *fd);
+
+#if defined(_PR_INET6_PROBE)
+
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+
+PR_IMPLEMENT(PRBool) _pr_test_ipv6_socket()
+{
+PRInt32 osfd;
+
+	osfd = _PR_MD_SOCKET(AF_INET6, SOCK_STREAM, 0);
+	if (osfd != -1) {
+		_PR_MD_CLOSE_SOCKET(osfd);
+		return PR_TRUE;
+	}
+	return PR_FALSE;
+}
+#endif	/* _PR_INET6_PROBE */
+
+#endif
 
 PR_IMPLEMENT(PRFileDesc*) PR_Socket(PRInt32 domain, PRInt32 type, PRInt32 proto)
 {
 	PRInt32 osfd;
 	PRFileDesc *fd;
+	PRInt32 tmp_domain = domain;
 
 	if (!_pr_initialized) _PR_ImplicitInitialization();
-	if (AF_INET != domain
-#if defined(_PR_INET6)
-			&& AF_INET6 != domain
-#endif
+	if (PR_AF_INET != domain
+			&& PR_AF_INET6 != domain
 #if defined(XP_UNIX)
-			&& AF_UNIX != domain
+			&& PR_AF_LOCAL != domain
 #endif
 			) {
 		PR_SetError(PR_ADDRESS_NOT_SUPPORTED_ERROR, 0);
 		return NULL;
 	}
+
+#if defined(_PR_INET6)
+	if (PR_AF_INET6 == domain) {
+#if defined(_PR_INET6_PROBE)
+        if (_pr_ipv6_is_present == PR_FALSE) 
+            domain = AF_INET;
+        else
+#endif
+		domain = AF_INET6;
+    }
+#elif defined(_PR_INET6_PROBE)
+	if (PR_AF_INET6 == domain) {
+		if (_pr_ipv6_is_present == PR_FALSE) 
+			domain = AF_INET;
+		else
+			domain = AF_INET6;
+	}
+#else
+	if (PR_AF_INET6 == domain)
+		domain = AF_INET;
+#endif	/* _PR_INET6 */
 	osfd = _PR_MD_SOCKET(domain, type, proto);
 	if (osfd == -1) {
 		return 0;
 	}
 	if (type == SOCK_STREAM)
 		fd = PR_AllocFileDesc(osfd, PR_GetTCPMethods());
 	else
 		fd = PR_AllocFileDesc(osfd, PR_GetUDPMethods());
 	/*
 	 * Make the sockets non-blocking
 	 */
-	if (fd != NULL)
+	if (fd != NULL) {
 		_PR_MD_MAKE_NONBLOCK(fd);
-	else
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		/*
+		 * For platforms with no support for IPv6 
+		 * create layered socket for IPv4-mapped IPv6 addresses
+		 */
+		if (PR_AF_INET6 == tmp_domain && PR_AF_INET == domain) {
+			if (PR_FAILURE == _pr_push_ipv6toipv4_layer(fd)) {
+				PR_Close(fd);
+				fd = NULL;
+			}
+		}
+#endif
+	} else
 		_PR_MD_CLOSE_SOCKET(osfd);
+
 	return fd;
 }
 
 PR_IMPLEMENT(PRFileDesc *) PR_NewTCPSocket(void)
 {
 	PRInt32 domain = AF_INET;
 
-#if defined(_PR_INET6)
-	if (_pr_ipv6_enabled) {
-		domain = AF_INET6;
-	}
-#endif
 	return PR_Socket(domain, SOCK_STREAM, 0);
 }
 
 PR_IMPLEMENT(PRFileDesc*) PR_NewUDPSocket(void)
 {
 	PRInt32 domain = AF_INET;
 
-#if defined(_PR_INET6)
-	if (_pr_ipv6_enabled) {
-		domain = AF_INET6;
-	}
-#endif
 	return PR_Socket(domain, SOCK_DGRAM, 0);
 }
 
 PR_IMPLEMENT(PRFileDesc *) PR_OpenTCPSocket(PRIntn af)
 {
 	return PR_Socket(af, SOCK_STREAM, 0);
 }
 
--- a/pr/src/linking/prlink.c
+++ b/pr/src/linking/prlink.c
@@ -26,17 +26,16 @@
 
 #ifdef XP_MAC
 #include <CodeFragments.h>
 #include <TextUtils.h>
 #include <Types.h>
 #include <Strings.h>
 #include <Aliases.h>
 
-#include "prlink_mac.h"
 #include "macdll.h"
 #include "mdmac.h"
 #endif
 
 #ifdef XP_UNIX
 #ifdef USE_DLFCN
 #include <dlfcn.h>
 /* Define these on systems that don't have them. */
@@ -256,16 +255,17 @@ void _PR_ShutdownLinker(void)
 #endif
 
 /******************************************************************************/
 
 PR_IMPLEMENT(PRStatus) PR_SetLibraryPath(const char *path)
 {
     PRStatus rv = PR_SUCCESS;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     PR_FREEIF(_pr_currentLibPath);
     if (path) {
         _pr_currentLibPath = strdup(path);
         if (!_pr_currentLibPath) {
             PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         rv = PR_FAILURE;
         }
@@ -280,16 +280,17 @@ PR_IMPLEMENT(PRStatus) PR_SetLibraryPath
 ** Return the library path for finding shared libraries.
 */
 PR_IMPLEMENT(char *) 
 PR_GetLibraryPath()
 {
     char *ev;
     char *copy = NULL;  /* a copy of _pr_currentLibPath */
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     if (_pr_currentLibPath != NULL) {
         goto exit;
     }
 
     /* initialize pr_currentLibPath */
 
 #ifdef XP_PC
@@ -793,36 +794,26 @@ pr_LoadLibraryByPathname(const char *nam
     return result;
 }
 
 PR_IMPLEMENT(PRLibrary*) 
 PR_FindLibrary(const char *name)
 {
     PRLibrary* result;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     PR_EnterMonitor(pr_linker_lock);
     result = pr_UnlockedFindLibrary(name);
     PR_ExitMonitor(pr_linker_lock);
     return result;
 }
 
 
 #ifdef XP_MAC
 
-PR_IMPLEMENT(PRLibrary*) 
-PR_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName)
-{
-    PRLibSpec libSpec;
-
-    libSpec.type = PR_LibSpec_MacNamedFragment;
-    libSpec.value.mac_named_fragment.fsspec = fileSpec;
-    libSpec.value.mac_named_fragment.name = fragmentName;
-    return PR_LoadLibraryWithFlags(libSpec, 0);
-}
-
 static PRLibrary*
 pr_Mac_LoadNamedFragment(const FSSpec *fileSpec, const char* fragmentName)
 {
 	PRLibrary*					newLib = NULL;
 	PRLibrary* 					result;
 	FSSpec							resolvedSpec = *fileSpec;
 	CFragConnectionID		connectionID = 0;
 	Boolean							isFolder, wasAlias;
@@ -870,27 +861,16 @@ unlock:
 		PR_SetError(PR_LOAD_LIBRARY_ERROR, _MD_ERRNO());
 		DLLErrorInternal(_MD_ERRNO());  /* sets error text */
 	}
 	PR_ExitMonitor(pr_linker_lock);
 	return result;
 }
 
 
-PR_EXTERN(PRLibrary*)
-PR_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex)
-{
-    PRLibSpec libSpec;
-
-    libSpec.type = PR_LibSpec_MacIndexedFragment;
-    libSpec.value.mac_indexed_fragment.fsspec = fileSpec;
-    libSpec.value.mac_indexed_fragment.index = fragIndex;
-    return PR_LoadLibraryWithFlags(libSpec, 0);
-}
-
 static PRLibrary*
 pr_Mac_LoadIndexedFragment(const FSSpec *fileSpec, PRUint32 fragIndex)
 {
 	PRLibrary*					newLib = NULL;
 	PRLibrary* 					result;
 	FSSpec							resolvedSpec = *fileSpec;
 	char*								fragmentName = NULL;
 	UInt32              fragOffset, fragLength;                
@@ -1161,16 +1141,17 @@ PR_FindSymbolAndLibrary(const char *raw_
     void *f = NULL;
 #if defined(NEED_LEADING_UNDERSCORE)
     char *name;
 #else
     const char *name;
 #endif
     PRLibrary* lm;
 
+    if (!_pr_initialized) _PR_ImplicitInitialization();
     /*
     ** Mangle the raw symbol name in any way that is platform specific.
     */
 #if defined(NEED_LEADING_UNDERSCORE)
     /* Need a leading _ */
     name = PR_smprintf("_%s", raw_name);
 #elif defined(AIX)
     /*
--- a/pr/src/md/mac/macsocket.h
+++ b/pr/src/md/mac/macsocket.h
@@ -159,18 +159,16 @@ extern int select (int nfds, fd_set *rea
 #define macsock_read PR_Read
 #define macsock_close PR_Close
 #define macsock_accept PR_Accept
 #define macsock_bind PR_Bind
 #define macsock_listen PR_Listen
 #define macsock_shutdown PR_Shutdown
 #define macsock_getpeername PR_GetPeerName
 #define macsock_getsockname PR_GetSockName
-#define macsock_getsockopt PR_GetSockOpt
-#define macsock_setsockopt PR_SetSockOpt
 #define macsock_socketavailable PR_SocketAvailable
 #define macsock_send PR_Send
 #define macsock_sendto PR_SendTo
 #define macsock_recvfrom PR_RecvFrom
 #define macsock_recv PR_Recv
 
 #ifdef __cplusplus
 }
--- a/pr/src/md/mac/macsockotpt.c
+++ b/pr/src/md/mac/macsockotpt.c
@@ -238,28 +238,44 @@ static void macsock_map_error(OSStatus e
 static void PrepareForAsyncCompletion(PRThread * thread, PRInt32 osfd)
 {
     thread->io_pending       = PR_TRUE;
     thread->io_fd            = osfd;
     thread->md.osErrCode     = noErr;
 }
 
 
+static void
+WakeUpNotifiedThread(PRThread *thread, OTResult result)
+{
+    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
+
+	if (thread) {
+		thread->md.osErrCode = result;
+		if (_PR_MD_GET_INTSOFF()) {
+			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
+			thread->md.missedIONotify = PR_TRUE;
+			return;
+		}
+		DoneWaitingOnThisThread(thread);
+	}
+}
+
 // Notification routine
 // Async callback routine.
 // A5 is OK. Cannot allocate memory here
 pascal void  NotifierRoutine(void * contextPtr, OTEventCode code, OTResult result, void * cookie)
 {
 	PRFilePrivate *secret  = (PRFilePrivate *) contextPtr;
 	_MDFileDesc * md       = &(secret->md);
 	EndpointRef   endpoint = (EndpointRef)secret->md.osfd;
     PRThread *    thread   = NULL;
-    _PRCPU *      cpu      = _PR_MD_CURRENT_CPU(); 
 	OSStatus      err;
 	OTResult	  resultOT;
+    TDiscon		  discon;
 
     switch (code)
     {
 // OTLook Events - 
         case T_LISTEN:        // A connection request is available
         	// If md->doListen is true, then PR_Listen has been
         	// called on this endpoint; therefore, we're ready to
         	// accept connections. But we'll do that with PR_Accept
@@ -298,36 +314,59 @@ pascal void  NotifierRoutine(void * cont
             secret->md.read.cookie    = cookie;
 			break;
 
         case T_EXDATA:      // Expedited data is available
             PR_ASSERT(!"T_EXDATA Not implemented");
 			return;
 
         case T_DISCONNECT:  // A disconnect is available
-            err = OTRcvDisconnect(endpoint, NULL);
+            discon.udata.len = 0;
+            err = OTRcvDisconnect(endpoint, &discon);
             PR_ASSERT(err == kOTNoError);
             secret->md.exceptReady     = PR_TRUE;
             secret->md.connectionOpen  = PR_FALSE;
+
+			// wake up waiting threads, if any
+			result = -3199 - discon.reason; // obtain the negative error code
+
+            if ((thread = secret->md.read.thread) != NULL) {
+		        secret->md.read.thread    = NULL;
+    	        secret->md.read.cookie    = cookie;
+            	WakeUpNotifiedThread(thread, result);
+    	    }
+            
+            if ((thread = secret->md.write.thread) != NULL) {
+	            secret->md.write.thread    = NULL;
+	            secret->md.write.cookie    = cookie;
+	            WakeUpNotifiedThread(thread, result);
+	        }
+	        
+	        thread = NULL; // already took care of notification here
             break;
 		
         case T_ERROR:       // obsolete/unused in library
             PR_ASSERT(!"T_ERROR Not implemented");
 			return;		
 		
         case T_UDERR:       // UDP Send error; clear the error
 			(void) OTRcvUDErr((EndpointRef) cookie, NULL);
             break;
 
         case T_ORDREL:      // An orderly release is available
             err = OTRcvOrderlyDisconnect(endpoint);
             PR_ASSERT(err == kOTNoError);
             secret->md.readReady      = PR_TRUE;   // mark readable (to emulate bsd sockets)
             // remember connection is closed, so we can return 0 on read or receive
 			secret->md.connectionOpen = PR_FALSE;
+	
+            thread = secret->md.read.thread;
+	        secret->md.read.thread    = NULL;
+	        secret->md.read.cookie    = cookie;
+
             break;		
 
         case T_GODATA:   // Flow control lifted on standard data
             secret->md.writeReady = PR_TRUE;
 			resultOT = OTLook(endpoint);		// clear T_GODATA event
 			PR_ASSERT(resultOT == T_GODATA);
 			
 			// wake up waiting thread, if any
@@ -386,26 +425,17 @@ pascal void  NotifierRoutine(void * cont
 //      case T_DNRMAILEXCHANGECOMPLETE:
 //      case T_DNRQUERYCOMPLETE:
         default:
         	// we should probably have a bit more sophisticated handling of kOTSystemSleep, etc.
 			// PR_ASSERT(code != 0);
             return;
     }
 
-	if (thread) {
-		thread->md.osErrCode = result;
-		if (_PR_MD_GET_INTSOFF()) {
-			cpu->u.missed[cpu->where] |= _PR_MISSED_IO;
-			thread->md.missedIONotify = PR_TRUE;
-			return;
-		}
-
-		DoneWaitingOnThisThread(thread);
-	}
+	WakeUpNotifiedThread(thread, result);
 }
 
 
 static OSErr CreateSocket(int type, EndpointRef *endpoint)
 {
     OSStatus err;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     char *  configName;
@@ -983,17 +1013,17 @@ PRInt32 _MD_socketavailable(PRFileDesc *
         err = kEBADFErr;
         goto ErrorExit;
     }
     
     bytes = 0;
     
     err = OTCountDataBytes(endpoint, &bytes);
     if ((err == kOTLookErr) ||         // Not really errors, we just need to do a read,
-        (err == kOTNoDataErr))        // or there’s nothing there.
+        (err == kOTNoDataErr))        // or there's nothing there.
         err = kOTNoError;
         
     if (err != kOTNoError)
         goto ErrorExit;
         
     return bytes;
 
 ErrorExit:
--- a/pr/src/md/mac/prcpucfg.h
+++ b/pr/src/md/mac/prcpucfg.h
@@ -21,16 +21,18 @@
 
 #ifndef XP_MAC
 #define XP_MAC
 #endif
 
 #undef  IS_LITTLE_ENDIAN
 #define IS_BIG_ENDIAN 1
 
+#define PR_AF_INET6 30  /* same as AF_INET6 */
+
 #define PR_BYTES_PER_BYTE   1L
 #define PR_BYTES_PER_SHORT  2L
 #define PR_BYTES_PER_INT    4L
 #define PR_BYTES_PER_INT64  8L
 #define PR_BYTES_PER_LONG   4L
 #define PR_BYTES_PER_FLOAT  4L
 #define PR_BYTES_PER_DOUBLE 8L
 #define PR_BYTES_PER_WORD   4L
--- a/pr/src/md/windows/Makefile
+++ b/pr/src/md/windows/Makefile
@@ -35,16 +35,17 @@ CSRCS = \
     w16stdio.c  \
     w16callb.c \
     ntinrval.c \
     $(NULL)
 else
 ifeq ($(OS_TARGET), WIN95)
 CSRCS =          \
     ntmisc.c \
+    ntsec.c   \
     ntsem.c   \
     ntinrval.c \
     ntgc.c \
 	w95thred.c \
 	w95io.c \
 	w95cv.c \
 	w32rng.c \
 	w95sock.c \
@@ -53,16 +54,17 @@ CSRCS =          \
     w32poll.c \
     w32shm.c \
     w95dllmain.c \
     $(NULL)
 else
 CSRCS =          \
     ntdllmn.c \
     ntmisc.c \
+    ntsec.c   \
     ntsem.c   \
     ntinrval.c \
     ntgc.c \
     ntthread.c \
     ntio.c    \
 	win32_errors.c \
     w32ipcsem.c \
     w32poll.c \
--- a/pr/src/md/windows/ntio.c
+++ b/pr/src/md/windows/ntio.c
@@ -32,16 +32,17 @@
  * be incorrectly completed on the GLOBAL_SCOPE IO thread; this will mean
  * extra context switching; but I don't think there is anything I can do
  * about it.
  */
 
 #include "primpl.h"
 #include "pprmwait.h"
 #include <direct.h>
+#include <mbstring.h>
 
 static HANDLE                _pr_completion_port;
 static PRThread             *_pr_io_completion_thread;
 
 #define RECYCLE_SIZE 512
 static struct _MDLock        _pr_recycle_lock;
 static PRInt32               _pr_recycle_array[RECYCLE_SIZE];
 static PRInt32               _pr_recycle_tail = 0; 
@@ -55,36 +56,50 @@ PRBool                       _nt_version
 struct _MDLock               _pr_ioq_lock;
 extern _MDLock               _nt_idleLock;
 extern PRCList               _nt_idleList;
 extern PRUint32              _nt_idleCount;
 
 #define CLOSE_TIMEOUT   PR_SecondsToInterval(5)
 
 /*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
  * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  * We store the value in a PRTime variable for convenience.
  * This constant is used by _PR_FileTimeToPRTime().
  */
 static const PRTime _pr_filetime_offset = 116444736000000000i64;
 
 #define _NEED_351_FILE_LOCKING_HACK
 #ifdef _NEED_351_FILE_LOCKING_HACK
 #define _PR_LOCAL_FILE 1
 #define _PR_REMOTE_FILE 2
 PRBool IsFileLocalInit();
 PRInt32 IsFileLocal(HANDLE hFile);
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
 static PRInt32 _md_MakeNonblock(HANDLE);
 
-/* The _nt_use_async flag is used to prevent nspr from using any async io.
- * this is a temporary hack.  Don't learn to rely on it.
- */
-static int _nt_use_async = 1;
 PRInt32 _nt_nonblock_accept(PRFileDesc *fd, struct sockaddr_in *addr, int *len, PRIntervalTime);
 PRInt32 _nt_nonblock_recv(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_send(PRFileDesc *fd, char *buf, int len, PRIntervalTime);
 PRInt32 _nt_nonblock_writev(PRFileDesc *fd, const PRIOVec *iov, int size, PRIntervalTime);
 PRInt32 _nt_nonblock_sendto(PRFileDesc *, const char *, int, const struct sockaddr *, int, PRIntervalTime);
 PRInt32 _nt_nonblock_recvfrom(PRFileDesc *, char *, int, struct sockaddr *, int *, PRIntervalTime);
 
 /*
@@ -884,16 +899,18 @@ void
         systime.wSecond = 0;
         systime.wMilliseconds = 0;
 
         rv = SystemTimeToFileTime(&systime, &filetime.ft);
         PR_ASSERT(0 != rv);
         PR_ASSERT(filetime.prt == _pr_filetime_offset);
     }
 #endif /* DEBUG */
+
+    _PR_NT_InitSids();
 }
 
 /* --- SOCKET IO --------------------------------------------------------- */
 
 /* _md_get_recycled_socket()
  * Get a socket from the recycle bin; if no sockets are in the bin,
  * create one.  The socket will be passed to AcceptEx() as the
  * second argument.
@@ -908,21 +925,16 @@ static SOCKET
     if (_pr_recycle_tail) {
         _pr_recycle_tail--;
         rv = _pr_recycle_array[_pr_recycle_tail];
         _MD_UNLOCK(&_pr_recycle_lock);
         return rv;
     }
     _MD_UNLOCK(&_pr_recycle_lock);
 
-#ifdef _PR_INET6
-    if (_pr_ipv6_enabled) {
-        af = AF_INET6;
-    }
-#endif
     rv = _PR_MD_SOCKET(af, SOCK_STREAM, 0);
     if (rv != INVALID_SOCKET && _md_Associate((HANDLE)rv) == 0) {
         closesocket(rv);
         return INVALID_SOCKET;
     }
     return rv;
 }
 
@@ -1122,17 +1134,17 @@ PRInt32
                PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 rv;
     PRThread *cThread;
     struct connect_data_s cd;
 
-    if (!_nt_use_async || fd->secret->nonblocking) {
+    if (fd->secret->nonblocking) {
         PRInt32 rv;
         fd_set wd;
         struct timeval tv, *tvp;
 
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
@@ -1289,29 +1301,29 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     SOCKET accept_sock;
     int bytes;
     PRNetAddr *Laddr;
     PRNetAddr *Raddr;
     PRUint32 llen, err;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         /*
          * The accepted socket inherits the nonblocking and
          * inheritable (HANDLE_FLAG_INHERIT) attributes of
          * the listening socket.
          */
         accept_sock = _nt_nonblock_accept(fd, (struct sockaddr_in *)raddr, rlen, timeout);
-        if (_nt_use_async && !fd->secret->nonblocking) {
+        if (!fd->secret->nonblocking) {
             u_long zero = 0;
 
             rv = ioctlsocket(accept_sock, FIONBIO, &zero);
             PR_ASSERT(0 == rv);
         }
         return accept_sock;
     }
 
@@ -1436,31 +1448,16 @@ PRInt32
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     PRNetAddr *Laddr;
     PRUint32 llen, rlen, err;
     int rv;
     PRBool isConnected;
     PRBool madeCallback = PR_FALSE;
 
-    if (!_nt_use_async) {
-        PRFileDesc *nd;
-        bytes = _PR_EmulateAcceptRead(sd, &nd, raddr, buf, amount, timeout);
-        if (bytes != -1) {
-            /*
-             * This part is the same as SocketClose(nd), except
-             * that we don't close the osfd.
-             */
-            PR_ASSERT(nd->secret->state == _PR_FILEDESC_OPEN);
-            *newSock = nd->secret->md.osfd;
-            PR_FreeFileDesc(nd);
-        }
-        return bytes;
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sd->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock);
         PR_ASSERT(0 != rv);
@@ -1615,25 +1612,16 @@ retry:
 PRInt32
 _PR_MD_SENDFILE(PRFileDesc *sock, PRSendFileData *sfd,
 					PRInt32 flags, PRIntervalTime timeout)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
     PRInt32 tflags;
     int rv, err;
 
-    if (!_nt_use_async) {
-        if (!sock->secret->md.io_model_committed) {
-            rv = _md_MakeNonblock((HANDLE)sock->secret->md.osfd);
-            PR_ASSERT(0 != rv);
-            sock->secret->md.io_model_committed = PR_TRUE;
-        }
-        return _PR_EmulateSendFile(sock, sfd, flags, timeout);
-    }
-
     if (me->io_suspended) {
         PR_SetError(PR_INVALID_STATE_ERROR, 0);
         return -1;
     }
 
     if (!sock->secret->md.io_model_committed) {
         rv = _md_Associate((HANDLE)sock->secret->md.osfd);
         PR_ASSERT(0 != rv);
@@ -1730,17 +1718,17 @@ PRInt32
 _PR_MD_RECV(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags, 
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_recv(fd, buf, amount, timeout);
     }
 
@@ -1829,17 +1817,17 @@ PRInt32
 _PR_MD_SEND(PRFileDesc *fd, const void *buf, PRInt32 amount, PRIntn flags,
             PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     PRThread *me = _PR_MD_CURRENT_THREAD();
     int bytes;
     int rv, err;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_send(fd, (char *)buf, amount, timeout);
     }
 
@@ -1927,17 +1915,17 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_SendTo(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_sendto(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 PRInt32
 _PR_MD_RECVFROM(PRFileDesc *fd, void *buf, PRInt32 amount, PRIntn flags,
                 PRNetAddr *addr, PRUint32 *addrlen, PRIntervalTime timeout)
@@ -1945,32 +1933,32 @@ PRInt32
     PRInt32 osfd = fd->secret->md.osfd;
     PRInt32 rv;
 
     if (!fd->secret->md.io_model_committed) {
         rv = _md_MakeNonblock((HANDLE)osfd);
         PR_ASSERT(0 != rv);
         fd->secret->md.io_model_committed = PR_TRUE;
     }
-    if (_nt_use_async && !fd->secret->nonblocking && !fd->secret->inheritable)
+    if (!fd->secret->nonblocking && !fd->secret->inheritable)
         return pt_RecvFrom(osfd, buf, amount, flags, addr, addrlen, timeout);
     else
         return _nt_nonblock_recvfrom(fd, buf, amount, (struct sockaddr *)addr, addrlen, timeout);
 }
 
 /* XXXMB - for now this is a sockets call only */
 PRInt32
 _PR_MD_WRITEV(PRFileDesc *fd, const PRIOVec *iov, PRInt32 iov_size, PRIntervalTime timeout)
 {
     PRInt32 osfd = fd->secret->md.osfd;
     int index;
     int sent = 0;
     int rv;
 
-    if (!_nt_use_async || fd->secret->nonblocking || fd->secret->inheritable) {
+    if (fd->secret->nonblocking || fd->secret->inheritable) {
         if (!fd->secret->md.io_model_committed) {
             rv = _md_MakeNonblock((HANDLE)osfd);
             PR_ASSERT(0 != rv);
             fd->secret->md.io_model_committed = PR_TRUE;
         }
         return _nt_nonblock_writev(fd, iov, iov_size, timeout);
     }
 
@@ -2110,126 +2098,154 @@ PRInt32
 {
     HANDLE file;
     PRInt32 access = 0;
     PRInt32 flags = 0;
     PRInt32 flag6 = 0;
     
     if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
  
-    if (_nt_use_async)
-    {
-        if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE)
-            flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
-        else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
-        else flags = OPEN_EXISTING;
-
-        
-        flag6 |= FILE_FLAG_OVERLAPPED;
-
-        file = CreateFile(name, 
-                          access, 
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags, 
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      NULL,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
             return -1;
         }
-
-        if (osflags & PR_APPEND) {
-            if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
-                _PR_MD_MAP_LSEEK_ERROR(GetLastError());
-                CloseHandle(file);
-                return -1;
-            }
-        }
-
-        return (PRInt32)file;
     }
-    else
-    {
-   
-        if (osflags & PR_RDONLY || osflags & PR_RDWR)
-            access |= GENERIC_READ;
-        if (osflags & PR_WRONLY || osflags & PR_RDWR)
-            access |= GENERIC_WRITE;
-
-        if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
-            flags = CREATE_NEW;
-        else if (osflags & PR_CREATE_FILE) {
-            if (osflags & PR_TRUNCATE)
-                flags = CREATE_ALWAYS;
-            else
-                flags = OPEN_ALWAYS;
-        } else {
-            if (osflags & PR_TRUNCATE)
-                flags = TRUNCATE_EXISTING;
-            else
-                flags = OPEN_EXISTING;
+
+    return (PRInt32)file;
+}
+
+PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, PRIntn mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR) access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR) access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE)
+        flags = (0 != (osflags & PR_TRUNCATE)) ? CREATE_ALWAYS : OPEN_ALWAYS;
+    else if (osflags & PR_TRUNCATE) flags = TRUNCATE_EXISTING;
+    else flags = OPEN_EXISTING;
+
+
+    flag6 |= FILE_FLAG_OVERLAPPED;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
         }
-
-        file = CreateFile(name,
-                          access,
-                          FILE_SHARE_READ|FILE_SHARE_WRITE,
-                          NULL,
-                          flags,
-                          flag6,
-                          NULL);
-        if (file == INVALID_HANDLE_VALUE) {
-            _PR_MD_MAP_OPEN_ERROR(GetLastError());
-            return -1; 
+    }
+    file = CreateFile(name, 
+                      access, 
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags, 
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+        _PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1;
+    }
+
+    if (osflags & PR_APPEND) {
+        if ( SetFilePointer(file, 0, 0, FILE_END) == 0xFFFFFFFF ) {
+            _PR_MD_MAP_LSEEK_ERROR(GetLastError());
+            CloseHandle(file);
+            return -1;
         }
-
-        return (PRInt32)file;
     }
+
+    return (PRInt32)file;
 }
 
 PRInt32 
 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRUint32 bytes;
     int rv, err;
-
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    LONG hiOffset = 0;
+    LONG loOffset;
+
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
 
-        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
 
         if (fd->secret->inheritable) {
             rv = ReadFile((HANDLE)f, 
                           (LPVOID)buf, 
                           len, 
                           &bytes, 
                           &me->md.overlapped.overlapped);
             if (rv != 0) {
-                SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                 return bytes;
             }
             err = GetLastError();
             if (err == ERROR_IO_PENDING) {
                 rv = GetOverlappedResult((HANDLE)f,
                         &me->md.overlapped.overlapped, &bytes, TRUE);
                 if (rv != 0) {
-                    SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                     return bytes;
                 }
                 err = GetLastError();
             }
             if (err == ERROR_HANDLE_EOF) {
                 return 0;
             } else {
                 _PR_MD_MAP_READ_ERROR(err);
@@ -2337,45 +2353,50 @@ PRInt32
 }
 
 PRInt32
 _PR_MD_WRITE(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRInt32 f = fd->secret->md.osfd;
     PRInt32 bytes;
     int rv, err;
-
-    if (_nt_use_async && !fd->secret->md.sync_file_io) {
+    LONG hiOffset = 0;
+    LONG loOffset;
+
+    if (!fd->secret->md.sync_file_io) {
         PRThread *me = _PR_MD_CURRENT_THREAD();
 
         if (me->io_suspended) {
             PR_SetError(PR_INVALID_STATE_ERROR, 0);
             return -1;
         }
 
         memset(&(me->md.overlapped.overlapped), 0, sizeof(OVERLAPPED));
 
-        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, 0, FILE_CURRENT);
+        me->md.overlapped.overlapped.Offset = SetFilePointer((HANDLE)f, 0, &me->md.overlapped.overlapped.OffsetHigh, FILE_CURRENT);
+        PR_ASSERT((me->md.overlapped.overlapped.Offset != 0xffffffff) || (GetLastError() == NO_ERROR));
 
         if (fd->secret->inheritable) {
             rv = WriteFile((HANDLE)f, 
                           (LPVOID)buf, 
                           len, 
                           &bytes, 
                           &me->md.overlapped.overlapped);
             if (rv != 0) {
-                SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                 return bytes;
             }
             err = GetLastError();
             if (err == ERROR_IO_PENDING) {
                 rv = GetOverlappedResult((HANDLE)f,
                         &me->md.overlapped.overlapped, &bytes, TRUE);
                 if (rv != 0) {
-                    SetFilePointer((HANDLE)f, bytes, 0, FILE_CURRENT);
+                    loOffset = SetFilePointer((HANDLE)f, bytes, &hiOffset, FILE_CURRENT);
+                    PR_ASSERT((loOffset != 0xffffffff) || (GetLastError() == NO_ERROR));
                     return bytes;
                 }
                 err = GetLastError();
             }
             _PR_MD_MAP_READ_ERROR(err);
             return -1;
         } else {
             if (!fd->secret->md.io_model_committed) {
@@ -2582,72 +2603,60 @@ PRInt32
     }
     return 0;
 }
 
 PRInt32
 _PR_MD_CLOSE(PRInt32 osfd, PRBool socket)
 {
     PRInt32 rv;
-    if (_nt_use_async) {
-        PRThread *me = _PR_MD_CURRENT_THREAD();
-
-        if (socket)  {
-            rv = closesocket((SOCKET)osfd);
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv < 0)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
-
-        if (rv == 0 && me->io_suspended) {
-            if (me->io_fd == osfd) {
-                PRBool fWait;
-
-                _PR_THREAD_LOCK(me);
-                me->state = _PR_IO_WAIT;
-                /* The IO could have completed on another thread just after
-                 * calling closesocket while the io_suspended flag was true.  
-                 * So we now grab the lock to do a safe check on io_pending to
-                 * see if we need to wait or not.
-                 */
-                fWait = me->io_pending;
-                me->io_suspended = PR_FALSE;
-                me->md.interrupt_disabled = PR_TRUE;
-                _PR_THREAD_UNLOCK(me);
-
-                if (fWait)
-                    _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
-                PR_ASSERT(me->io_suspended ==  PR_FALSE);
-                PR_ASSERT(me->io_pending ==  PR_FALSE);
-				/*
-				 * I/O operation is no longer pending; the thread can now
-				 * run on any cpu
-				 */
-                _PR_THREAD_LOCK(me);
-                me->md.interrupt_disabled = PR_FALSE;
-				me->md.thr_bound_cpu = NULL;
-                me->io_suspended = PR_FALSE;
-                me->io_pending = PR_FALSE;
-                me->state = _PR_RUNNING;
-                _PR_THREAD_UNLOCK(me);
-            }
+    PRThread *me = _PR_MD_CURRENT_THREAD();
+
+    if (socket)  {
+        rv = closesocket((SOCKET)osfd);
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
+    } else {
+        rv = CloseHandle((HANDLE)osfd)?0:-1;
+        if (rv < 0)
+            _PR_MD_MAP_CLOSE_ERROR(GetLastError());
+    }
+
+    if (rv == 0 && me->io_suspended) {
+        if (me->io_fd == osfd) {
+            PRBool fWait;
+
+            _PR_THREAD_LOCK(me);
+            me->state = _PR_IO_WAIT;
+            /* The IO could have completed on another thread just after
+             * calling closesocket while the io_suspended flag was true.  
+             * So we now grab the lock to do a safe check on io_pending to
+             * see if we need to wait or not.
+             */
+            fWait = me->io_pending;
+            me->io_suspended = PR_FALSE;
+            me->md.interrupt_disabled = PR_TRUE;
+            _PR_THREAD_UNLOCK(me);
+
+            if (fWait)
+                _NT_IO_WAIT(me, PR_INTERVAL_NO_TIMEOUT);
+            PR_ASSERT(me->io_suspended ==  PR_FALSE);
+            PR_ASSERT(me->io_pending ==  PR_FALSE);
+            /*
+             * I/O operation is no longer pending; the thread can now
+             * run on any cpu
+             */
+            _PR_THREAD_LOCK(me);
+            me->md.interrupt_disabled = PR_FALSE;
+            me->md.thr_bound_cpu = NULL;
+            me->io_suspended = PR_FALSE;
+            me->io_pending = PR_FALSE;
+            me->state = _PR_RUNNING;
+            _PR_THREAD_UNLOCK(me);
         }
-    } else { 
-        if (socket) {
-            rv = closesocket((SOCKET)osfd);
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(WSAGetLastError());
-        } else {
-            rv = CloseHandle((HANDLE)osfd)?0:-1;
-			if (rv == -1)
-				_PR_MD_MAP_CLOSE_ERROR(GetLastError());
-		}
     }
     return rv;
 }
 
 PRStatus
 _PR_MD_SET_FD_INHERITABLE(PRFileDesc *fd, PRBool inheritable)
 {
     BOOL rv;
@@ -2656,36 +2665,36 @@ PRStatus
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return PR_FAILURE;
     }
     rv = SetHandleInformation(
             (HANDLE)fd->secret->md.osfd,
             HANDLE_FLAG_INHERIT,
             inheritable ? HANDLE_FLAG_INHERIT : 0);
     if (0 == rv) {
-        PR_SetError(PR_UNKNOWN_ERROR, GetLastError());
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
         return PR_FAILURE;
     }
     return PR_SUCCESS;
 } 
 
 
 /* --- DIR IO ------------------------------------------------------------ */
 #define GetFileFromDIR(d)       (d)->d_entry.cFileName
 #define FileIsHidden(d)       ((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
 
 void FlipSlashes(char *cp, int len)
 {
     while (--len >= 0) {
-    if (cp[0] == '/') {
-        cp[0] = PR_DIRECTORY_SEPARATOR;
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
     }
-    cp++;
-    }
-}
+} /* end FlipSlashes() */
 
 /*
 **
 ** Local implementations of standard Unix RTL functions which are not provided
 ** by the VC RTL.
 **
 */
 
@@ -2974,17 +2983,17 @@ PRInt32
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return -1;
     }
 
     /*
      * FindFirstFile() expands wildcard characters.  So
      * we make sure the pathname contains no wildcard.
      */
-    if (NULL != strpbrk(fn, "?*")) {
+    if (NULL != _mbspbrk(fn, "?*")) {
         PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
         return -1;
     }
 
     hFindFile = FindFirstFile(fn, &findFileData);
     if (INVALID_HANDLE_VALUE == hFindFile) {
         DWORD len;
         char *filePart;
@@ -2996,17 +3005,17 @@ PRInt32
          * root directory.  If not, and if the pathname ends in a slash,
          * we remove the final slash and try again.
          */
 
         /*
          * If the pathname does not contain ., \, and /, it cannot be
          * a root directory or a pathname that ends in a slash.
          */
-        if (NULL == strpbrk(fn, ".\\/")) {
+        if (NULL == _mbspbrk(fn, ".\\/")) {
             _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
             return -1;
         } 
         len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
                 &filePart);
         PR_ASSERT(0 != len);
         if (len > sizeof(pathbuf)) {
             PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
@@ -3172,16 +3181,44 @@ PRInt32
         return 0;
     } else {
         _PR_MD_MAP_MKDIR_ERROR(GetLastError());
         return -1;
     }
 }
 
 PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
 _PR_MD_RMDIR(const char *name)
 {
     if (RemoveDirectory(name)) {
         return 0;
     } else {
         _PR_MD_MAP_RMDIR_ERROR(GetLastError());
         return -1;
     }
@@ -3663,21 +3700,16 @@ PRInt32 IsFileLocal(HANDLE hFile)
       dwIndex++;
       dwMask = dwMask >> 1;
    }
 
    return _PR_REMOTE_FILE;
 }
 #endif /* _NEED_351_FILE_LOCKING_HACK */
 
-PR_IMPLEMENT(void) PR_NT_UseNonblock()
-{
-    _nt_use_async = 0;
-}
-
 PR_IMPLEMENT(PRStatus) PR_NT_CancelIo(PRFileDesc *fd)
 {
     PRThread *me = _PR_MD_CURRENT_THREAD();
 	PRBool fWait;
 	PRFileDesc *bottom;
 
 	bottom = PR_GetIdentitiesLayer(fd, PR_NSPR_IO_LAYER);
     if (!me->io_suspended || (NULL == bottom) ||
new file mode 100644
--- /dev/null
+++ b/pr/src/md/windows/ntsec.c
@@ -0,0 +1,252 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ * The contents of this file are subject to the Netscape Public License
+ * Version 1.1 (the "NPL"); you may not use this file except in
+ * compliance with the NPL.  You may obtain a copy of the NPL at
+ * http://www.mozilla.org/NPL/
+ * 
+ * Software distributed under the NPL is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
+ * for the specific language governing rights and limitations under the
+ * NPL.
+ * 
+ * The Initial Developer of this code under the NPL is Netscape
+ * Communications Corporation.  Portions created by Netscape are
+ * Copyright (C) 2000 Netscape Communications Corporation.  All Rights
+ * Reserved.
+ */
+
+#include "primpl.h"
+
+/*
+ * ntsec.c
+ *
+ * Implement the POSIX-style mode bits (access permissions) for
+ * files and other securable objects in Windows NT using Windows
+ * NT's security descriptors with appropriate discretionary
+ * access-control lists.
+ */
+
+/*
+ * The security identifiers (SIDs) for owner, primary group,
+ * and the Everyone (World) group.
+ *
+ * These SIDs are looked up during NSPR initialization and
+ * saved in this global structure (see _PR_NT_InitSids) so
+ * that _PR_NT_MakeSecurityDescriptorACL doesn't need to
+ * look them up every time.
+ */
+static struct {
+    PSID owner;
+    PSID group;
+    PSID everyone;
+} _pr_nt_sids;
+
+/*
+ * Initialize the SIDs for owner, primary group, and the Everyone
+ * group in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR initialization.
+ */
+void _PR_NT_InitSids(void)
+{
+    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
+    HANDLE hToken;
+    UCHAR infoBuffer[1024];
+    PTOKEN_OWNER pTokenOwner = (PTOKEN_OWNER) infoBuffer;
+    PTOKEN_PRIMARY_GROUP pTokenPrimaryGroup
+            = (PTOKEN_PRIMARY_GROUP) infoBuffer;
+    DWORD dwLength;
+    BOOL rv;
+
+    /* Create a well-known SID for the Everyone group. */
+    if (!AllocateAndInitializeSid(&SIDAuthWorld, 1,
+            SECURITY_WORLD_RID,
+            0, 0, 0, 0, 0, 0, 0,
+            &_pr_nt_sids.everyone)) {
+        /*
+         * On non-NT systems, this function is not implemented,
+         * and neither are the other security functions. There
+         * is no point in going further.
+         */
+        PR_ASSERT(GetLastError() == ERROR_CALL_NOT_IMPLEMENTED);
+        return;
+    }
+
+    /*
+     * Look up and make a copy of the owner and primary group
+     * SIDs in the access token of the calling process.
+     */
+    rv = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken);
+    PR_ASSERT(rv != 0);
+
+    rv = GetTokenInformation(hToken, TokenOwner, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenOwner->Owner);
+    _pr_nt_sids.owner = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.owner != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.owner, pTokenOwner->Owner);
+    PR_ASSERT(rv != 0);
+
+    rv = GetTokenInformation(hToken, TokenPrimaryGroup, infoBuffer,
+            sizeof(infoBuffer), &dwLength);
+    PR_ASSERT(rv != 0);
+    dwLength = GetLengthSid(pTokenPrimaryGroup->PrimaryGroup);
+    _pr_nt_sids.group = (PSID) PR_Malloc(dwLength);
+    PR_ASSERT(_pr_nt_sids.group != NULL);
+    rv = CopySid(dwLength, _pr_nt_sids.group,
+            pTokenPrimaryGroup->PrimaryGroup);
+    PR_ASSERT(rv != 0);
+
+    rv = CloseHandle(hToken);
+    PR_ASSERT(rv != 0);
+}
+
+/*
+ * Free the SIDs for owner, primary group, and the Everyone group
+ * in the _pr_nt_sids structure.
+ *
+ * This function needs to be called by NSPR cleanup.
+ */
+void
+_PR_NT_FreeSids(void)
+{
+    if (_pr_nt_sids.owner) {
+        PR_Free(_pr_nt_sids.owner);
+    }
+    if (_pr_nt_sids.group) {
+        PR_Free(_pr_nt_sids.group);
+    }
+    if (_pr_nt_sids.everyone) {
+        FreeSid(_pr_nt_sids.everyone);
+    }
+}
+
+/*
+ * Construct a security descriptor whose discretionary access-control
+ * list implements the specified mode bits.  The SIDs for owner, group,
+ * and everyone are obtained from the global _pr_nt_sids structure.
+ * Both the security descriptor and access-control list are returned
+ * and should be freed by a _PR_NT_FreeSecurityDescriptorACL call.
+ *
+ * The accessTable array maps NSPR's read, write, and execute access
+ * rights to the corresponding NT access rights for the securable
+ * object.
+ */
+PRStatus
+_PR_NT_MakeSecurityDescriptorACL(
+    PRIntn mode,
+    DWORD accessTable[],
+    PSECURITY_DESCRIPTOR *resultSD,
+    PACL *resultACL)
+{
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+    DWORD cbACL;  /* size of ACL */
+    DWORD accessMask;
+
+    if (_pr_nt_sids.owner == NULL) {
+        PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+        return PR_FAILURE;
+    }
+
+    pSD = (PSECURITY_DESCRIPTOR) PR_Malloc(SECURITY_DESCRIPTOR_MIN_LENGTH);
+    if (pSD == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorOwner(pSD, _pr_nt_sids.owner, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!SetSecurityDescriptorGroup(pSD, _pr_nt_sids.group, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    /*
+     * Construct a discretionary access-control list with three
+     * access-control entries, one each for owner, primary group,
+     * and Everyone.
+     */
+
+    cbACL = sizeof(ACL)
+          + 3 * (sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD))
+          + GetLengthSid(_pr_nt_sids.owner)
+          + GetLengthSid(_pr_nt_sids.group)
+          + GetLengthSid(_pr_nt_sids.everyone);
+    pACL = (PACL) PR_Malloc(cbACL);
+    if (pACL == NULL) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    if (!InitializeAcl(pACL, cbACL, ACL_REVISION)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00400) accessMask |= accessTable[0];
+    if (mode & 00200) accessMask |= accessTable[1];
+    if (mode & 00100) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.owner)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00040) accessMask |= accessTable[0];
+    if (mode & 00020) accessMask |= accessTable[1];
+    if (mode & 00010) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.group)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+    accessMask = 0;
+    if (mode & 00004) accessMask |= accessTable[0];
+    if (mode & 00002) accessMask |= accessTable[1];
+    if (mode & 00001) accessMask |= accessTable[2];
+    if (accessMask && !AddAccessAllowedAce(pACL, ACL_REVISION, accessMask,
+            _pr_nt_sids.everyone)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    if (!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE)) {
+        _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
+        goto failed;
+    }
+
+    *resultSD = pSD;
+    *resultACL = pACL;
+    return PR_SUCCESS;
+
+failed:
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+    return PR_FAILURE;
+}
+
+/*
+ * Free the specified security descriptor and access-control list
+ * previously created by _PR_NT_MakeSecurityDescriptorACL.
+ */
+void
+_PR_NT_FreeSecurityDescriptorACL(PSECURITY_DESCRIPTOR pSD, PACL pACL)
+{
+    if (pSD) {
+        PR_Free(pSD);
+    }
+    if (pACL) {
+        PR_Free(pACL);
+    }
+}
--- a/pr/src/md/windows/ntthread.c
+++ b/pr/src/md/windows/ntthread.c
@@ -113,16 +113,18 @@ void
         _pr_currentCPUIndex = TlsAlloc();
         _pr_intsOffIndex = TlsAlloc();
         _pr_io_restartedIOIndex = TlsAlloc();
     }
 }
 
 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
 {
+    _PR_NT_FreeSids();
+
     WSACleanup();
 
     if (!_pr_use_static_tls) {
         TlsFree(_pr_currentFiberIndex);
         TlsFree(_pr_lastFiberIndex);
         TlsFree(_pr_currentCPUIndex);
         TlsFree(_pr_intsOffIndex);
         TlsFree(_pr_io_restartedIOIndex);
--- a/pr/src/md/windows/w32ipcsem.c
+++ b/pr/src/md/windows/w32ipcsem.c
@@ -18,16 +18,32 @@
 
 /*
  * File: w32ipcsem.c
  * Description: implements named semaphores for NT and WIN95.
  */
 
 #include "primpl.h"
 
+/*
+ * NSPR-to-NT access right mapping table for semaphore objects.
+ *
+ * The SYNCHRONIZE access is required by WaitForSingleObject.
+ * The SEMAPHORE_MODIFY_STATE access is required by ReleaseSemaphore.
+ * The OR of these three access masks must equal SEMAPHORE_ALL_ACCESS.
+ * This is because if a semaphore object with the specified name
+ * exists, CreateSemaphore requests SEMAPHORE_ALL_ACCESS access to
+ * the existing object.
+ */
+static DWORD semAccessTable[] = {
+    STANDARD_RIGHTS_REQUIRED|0x1, /* read (0x1 is "query state") */
+    STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, /* write */
+    0 /* execute */
+};
+
 #ifndef _PR_GLOBAL_THREADS_ONLY
 
 /*
  * A fiber cannot call WaitForSingleObject because that
  * will block the other fibers running on the same thread.
  * If a fiber needs to wait on a (semaphore) handle, we
  * create a native thread to call WaitForSingleObject and
  * have the fiber join the native thread.
@@ -89,37 +105,52 @@ static DWORD FiberSafeWaitForSingleObjec
 }
 
 #endif /* !_PR_GLOBAL_THREADS_ONLY */
 
 PRSem *_PR_MD_OPEN_SEMAPHORE(
     const char *osname, PRIntn flags, PRIntn mode, PRUintn value)
 {
     PRSem *sem;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
 
     sem = PR_NEW(PRSem);
     if (sem == NULL) {
         PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
         return NULL;
     }
     if (flags & PR_SEM_CREATE) {
-        sem->sem = CreateSemaphore(NULL, value, 0x7fffffff, osname);
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, semAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+        sem->sem = CreateSemaphore(lpSA, value, 0x7fffffff, osname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
         if (sem->sem == NULL) {
             _PR_MD_MAP_DEFAULT_ERROR(GetLastError());
             PR_DELETE(sem);
             return NULL;
         }
         if ((flags & PR_SEM_EXCL) && (GetLastError() == ERROR_ALREADY_EXISTS)) {
             PR_SetError(PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS);
             CloseHandle(sem->sem);
             PR_DELETE(sem);
             return NULL;
         }
     } else {
-        sem->sem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, osname);
+        sem->sem = OpenSemaphore(
+                SEMAPHORE_MODIFY_STATE|SYNCHRONIZE, FALSE, osname);
         if (sem->sem == NULL) {
             DWORD err = GetLastError();
 
             /*
              * If we open a nonexistent named semaphore, NT
              * returns ERROR_FILE_NOT_FOUND, while Win95
              * returns ERROR_INVALID_NAME
              */
--- a/pr/src/md/windows/w32shm.c
+++ b/pr/src/md/windows/w32shm.c
@@ -21,28 +21,46 @@
 #include <prshm.h>
 #include <prerr.h>
 #include <prmem.h>
 
 #if defined(PR_HAVE_WIN32_NAMED_SHARED_MEMORY)
 
 extern PRLogModuleInfo *_pr_shm_lm;
 
+/*
+ * NSPR-to-NT access right mapping table for file-mapping objects.
+ *
+ * The OR of these three access masks must equal FILE_MAP_ALL_ACCESS.
+ * This is because if a file-mapping object with the specified name
+ * exists, CreateFileMapping requests full access to the existing
+ * object.
+ */
+static DWORD filemapAccessTable[] = {
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_WRITE, /* read */
+    FILE_MAP_ALL_ACCESS & ~FILE_MAP_READ, /* write */ 
+    0  /* execute */
+};
+
 extern PRSharedMemory * _MD_OpenSharedMemory( 
         const char *name,
         PRSize      size,
         PRIntn      flags,
         PRIntn      mode
 )
 {
     char        ipcname[PR_IPC_NAME_SIZE];
     PRStatus    rc = PR_SUCCESS;
     DWORD dwHi, dwLo;
     PRSharedMemory *shm;
     DWORD flProtect = ( PAGE_READWRITE );
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
 
     rc = _PR_MakeNativeIPCName( name, ipcname, PR_IPC_NAME_SIZE, _PRIPCShm );
     if ( PR_FAILURE == rc )
     {
         PR_SetError(PR_UNKNOWN_ERROR, 0 );
         PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, ( "PR_OpenSharedMemory: name is invalid")); 
         return(NULL);
     }
@@ -67,33 +85,43 @@ extern PRSharedMemory * _MD_OpenSharedMe
     /* copy args to struct */
     strcpy( shm->ipcname, ipcname );
     shm->size = size; 
     shm->mode = mode;
     shm->flags = flags;
     shm->ident = _PR_SHM_IDENT;
 
     if (flags & PR_SHM_CREATE ) {
-        /* XXX: Not 64bit safe. Fix when WinNT goes 64bit, if ever */
+        /* XXX: Not 64bit safe. Fix when WinNT goes 64bit. */
         dwHi = 0;
         dwLo = shm->size;
 
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, filemapAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
         shm->handle = CreateFileMapping(
             (HANDLE)-1 ,
-            NULL,
+            lpSA,
             flProtect,
             dwHi,
             dwLo,
             shm->ipcname);
+        if (lpSA != NULL) {
+            _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+        }
 
         if ( NULL == shm->handle ) {
             PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                 ( "PR_OpenSharedMemory: CreateFileMapping() failed: %s",
                     shm->ipcname )); 
-            PR_SetError( PR_FILE_EXISTS_ERROR, ERROR_ALREADY_EXISTS );
+            _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
             PR_FREEIF( shm->ipcname )
             PR_DELETE( shm );
             return(NULL);
         } else {
             if (( flags & PR_SHM_EXCL) && ( GetLastError() == ERROR_ALREADY_EXISTS ))  {
                 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                     ( "PR_OpenSharedMemory: Request exclusive & already exists",
                         shm->ipcname )); 
@@ -105,17 +133,17 @@ extern PRSharedMemory * _MD_OpenSharedMe
             } else {
                 PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                     ( "PR_OpenSharedMemory: CreateFileMapping() success: %s, handle: %d",
                         shm->ipcname, shm->handle ));
                 return(shm);
             }
         }
     } else {
-        shm->handle = OpenFileMapping( FILE_MAP_ALL_ACCESS, TRUE, shm->ipcname );
+        shm->handle = OpenFileMapping( FILE_MAP_WRITE, TRUE, shm->ipcname );
         if ( NULL == shm->handle ) {
             _PR_MD_MAP_DEFAULT_ERROR( GetLastError());
             PR_LOG(_pr_shm_lm, PR_LOG_DEBUG, 
                 ( "PR_OpenSharedMemory: OpenFileMapping() failed: %s, error: %d",
                     shm->ipcname, PR_GetOSError())); 
             PR_FREEIF( shm->ipcname );
             PR_DELETE( shm );
             return(NULL);
--- a/pr/src/md/windows/w95io.c
+++ b/pr/src/md/windows/w95io.c
@@ -19,20 +19,40 @@
 /* Windows 95 IO module
  *
  * Assumes synchronous I/O.
  *
  */
 
 #include "primpl.h"
 #include <direct.h>
+#include <mbstring.h>
+
 
 struct _MDLock               _pr_ioq_lock;
 
 /*
+ * NSPR-to-NT access right mapping table for files.
+ */
+static DWORD fileAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
+ * NSPR-to-NT access right mapping table for directories.
+ */
+static DWORD dirAccessTable[] = {
+    FILE_GENERIC_READ,
+    FILE_GENERIC_WRITE|FILE_DELETE_CHILD,
+    FILE_GENERIC_EXECUTE
+};
+
+/*
  * The NSPR epoch (00:00:00 1 Jan 1970 UTC) in FILETIME.
  * We store the value in a PRTime variable for convenience.
  * This constant is used by _PR_FileTimeToPRTime().
  */
 #if defined(__MINGW32__)
 static const PRTime _pr_filetime_offset = 116444736000000000LL;
 #else
 static const PRTime _pr_filetime_offset = 116444736000000000i64;
@@ -67,16 +87,18 @@ void
         systime.wSecond = 0;
         systime.wMilliseconds = 0;
 
         rv = SystemTimeToFileTime(&systime, &filetime.ft);
         PR_ASSERT(0 != rv);
         PR_ASSERT(filetime.prt == _pr_filetime_offset);
     }
 #endif /* DEBUG */
+
+    _PR_NT_InitSids();
 }
 
 PRStatus
 _PR_MD_WAIT(PRThread *thread, PRIntervalTime ticks)
 {
     DWORD rv;
 
     PRUint32 msecs = (ticks == PR_INTERVAL_NO_TIMEOUT) ?
@@ -177,16 +199,77 @@ PRInt32
 		_PR_MD_MAP_OPEN_ERROR(GetLastError());
         return -1; 
 	}
 
     return (PRInt32)file;
 }
 
 PRInt32
+_PR_MD_OPEN_FILE(const char *name, PRIntn osflags, int mode)
+{
+    HANDLE file;
+    PRInt32 access = 0;
+    PRInt32 flags = 0;
+    PRInt32 flag6 = 0;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (osflags & PR_CREATE_FILE) {
+        if (_PR_NT_MakeSecurityDescriptorACL(mode, fileAccessTable,
+                &pSD, &pACL) == PR_SUCCESS) {
+            sa.nLength = sizeof(sa);
+            sa.lpSecurityDescriptor = pSD;
+            sa.bInheritHandle = FALSE;
+            lpSA = &sa;
+        }
+    }
+    
+    if (osflags & PR_SYNC) flag6 = FILE_FLAG_WRITE_THROUGH;
+ 
+    if (osflags & PR_RDONLY || osflags & PR_RDWR)
+        access |= GENERIC_READ;
+    if (osflags & PR_WRONLY || osflags & PR_RDWR)
+        access |= GENERIC_WRITE;
+
+    if ( osflags & PR_CREATE_FILE && osflags & PR_EXCL )
+        flags = CREATE_NEW;
+    else if (osflags & PR_CREATE_FILE) {
+        if (osflags & PR_TRUNCATE)
+            flags = CREATE_ALWAYS;
+        else
+            flags = OPEN_ALWAYS;
+    } else {
+        if (osflags & PR_TRUNCATE)
+            flags = TRUNCATE_EXISTING;
+        else
+            flags = OPEN_EXISTING;
+    }
+
+    file = CreateFile(name,
+                      access,
+                      FILE_SHARE_READ|FILE_SHARE_WRITE,
+                      lpSA,
+                      flags,
+                      flag6,
+                      NULL);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (file == INVALID_HANDLE_VALUE) {
+		_PR_MD_MAP_OPEN_ERROR(GetLastError());
+        return -1; 
+	}
+
+    return (PRInt32)file;
+}
+
+PRInt32
 _PR_MD_READ(PRFileDesc *fd, void *buf, PRInt32 len)
 {
     PRUint32 bytes;
     int rv, err;
 
     rv = ReadFile((HANDLE)fd->secret->md.osfd,
             (LPVOID)buf,
             len,
@@ -348,22 +431,23 @@ PRInt32
 
 /* --- DIR IO ------------------------------------------------------------ */
 #define GetFileFromDIR(d)       (d)->d_entry.cFileName
 #define FileIsHidden(d)	((d)->d_entry.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN)
 
 void FlipSlashes(char *cp, int len)
 {
     while (--len >= 0) {
-    if (cp[0] == '/') {
-        cp[0] = PR_DIRECTORY_SEPARATOR;
+        if (cp[0] == '/') {
+            cp[0] = PR_DIRECTORY_SEPARATOR;
+        }
+        cp = _mbsinc(cp);
     }
-    cp++;
-    }
-}
+} /* end FlipSlashes() */
+
 
 /*
 **
 ** Local implementations of standard Unix RTL functions which are not provided
 ** by the VC RTL.
 **
 */
 
@@ -656,17 +740,17 @@ PRInt32
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return -1;
     }
 
     /*
      * FindFirstFile() expands wildcard characters.  So
      * we make sure the pathname contains no wildcard.
      */
-    if (NULL != strpbrk(fn, "?*")) {
+    if (NULL != _mbspbrk(fn, "?*")) {
         PR_SetError(PR_FILE_NOT_FOUND_ERROR, 0);
         return -1;
     }
 
     hFindFile = FindFirstFile(fn, &findFileData);
     if (INVALID_HANDLE_VALUE == hFindFile) {
         DWORD len;
         char *filePart;
@@ -678,17 +762,17 @@ PRInt32
          * root directory.  If not, and if the pathname ends in a slash,
          * we remove the final slash and try again.
          */
 
         /*
          * If the pathname does not contain ., \, and /, it cannot be
          * a root directory or a pathname that ends in a slash.
          */
-        if (NULL == strpbrk(fn, ".\\/")) {
+        if (NULL == _mbspbrk(fn, ".\\/")) {
             _PR_MD_MAP_OPENDIR_ERROR(GetLastError());
             return -1;
         } 
         len = GetFullPathName(fn, sizeof(pathbuf), pathbuf,
                 &filePart);
         PR_ASSERT(0 != len);
         if (len > sizeof(pathbuf)) {
             PR_SetError(PR_NAME_TOO_LONG_ERROR, 0);
@@ -861,16 +945,44 @@ PRInt32
         return 0;
     } else {
 		_PR_MD_MAP_MKDIR_ERROR(GetLastError());
         return -1;
     }
 }
 
 PRInt32
+_PR_MD_MAKE_DIR(const char *name, PRIntn mode)
+{
+    BOOL rv;
+    SECURITY_ATTRIBUTES sa;
+    LPSECURITY_ATTRIBUTES lpSA = NULL;
+    PSECURITY_DESCRIPTOR pSD = NULL;
+    PACL pACL = NULL;
+
+    if (_PR_NT_MakeSecurityDescriptorACL(mode, dirAccessTable,
+            &pSD, &pACL) == PR_SUCCESS) {
+        sa.nLength = sizeof(sa);
+        sa.lpSecurityDescriptor = pSD;
+        sa.bInheritHandle = FALSE;
+        lpSA = &sa;
+    }
+    rv = CreateDirectory(name, lpSA);
+    if (lpSA != NULL) {
+        _PR_NT_FreeSecurityDescriptorACL(pSD, pACL);
+    }
+    if (rv) {
+        return 0;
+    } else {
+        _PR_MD_MAP_MKDIR_ERROR(GetLastError());
+        return -1;
+    }
+}
+
+PRInt32
 _PR_MD_RMDIR(const char *name)
 {
     if (RemoveDirectory(name)) {
         return 0;
     } else {
 		_PR_MD_MAP_RMDIR_ERROR(GetLastError());
         return -1;
     }
--- a/pr/src/md/windows/w95thred.c
+++ b/pr/src/md/windows/w95thred.c
@@ -43,16 +43,18 @@ void
     _pr_currentThreadIndex = TlsAlloc();
     _pr_lastThreadIndex = TlsAlloc();
     _pr_currentCPUIndex = TlsAlloc();
 #endif
 }
 
 void _PR_MD_CLEANUP_BEFORE_EXIT(void)
 {
+    _PR_NT_FreeSids();
+
     WSACleanup();
 
 #ifndef _PR_USE_STATIC_TLS
     TlsFree(_pr_currentThreadIndex);
     TlsFree(_pr_lastThreadIndex);
     TlsFree(_pr_currentCPUIndex);
 #endif
 }
--- a/pr/src/md/windows/win32_errors.c
+++ b/pr/src/md/windows/win32_errors.c
@@ -137,16 +137,19 @@ void _MD_win32_map_default_error(PRInt32
             prError = PR_NO_MORE_FILES_ERROR;
             break;
         case ERROR_OPEN_FAILED:
             prError = PR_IO_ERROR;
             break;
         case ERROR_OPEN_FILES:
             prError = PR_IO_ERROR;
             break;
+        case ERROR_OPERATION_ABORTED:
+            prError = PR_OPERATION_ABORTED_ERROR;
+            break;
         case ERROR_OUTOFMEMORY:
             prError = PR_INSUFFICIENT_RESOURCES_ERROR;
             break;
         case ERROR_PATH_BUSY:
             prError = PR_IO_ERROR;
             break;
         case ERROR_PATH_NOT_FOUND:
             prError = PR_FILE_NOT_FOUND_ERROR;
--- a/pr/src/misc/prerr.c
+++ b/pr/src/misc/prerr.c
@@ -83,17 +83,17 @@ static const struct PRErrorMessage text[
 	{"PR_FILE_EXISTS_ERROR",    "Cannot create or rename a filename that already exists"},
 	{"PR_MAX_DIRECTORY_ENTRIES_ERROR",    "Directory is full.  No additional filenames may be added"},
 	{"PR_INVALID_DEVICE_STATE_ERROR",    "The required device was in an invalid state"},
 	{"PR_DEVICE_IS_LOCKED_ERROR",    "The device is locked"},
 	{"PR_NO_MORE_FILES_ERROR",    "No more entries in the directory"},
 	{"PR_END_OF_FILE_ERROR",    "Encountered end of file"},
 	{"PR_FILE_SEEK_ERROR",    "Seek error"},
 	{"PR_FILE_IS_BUSY_ERROR",    "The file is busy"},
-	{"PR_RESERVED_ERROR_5935",    "Reserved Error Code -5935"},
+	{"PR_OPERATION_ABORTED_ERROR",    "The I/O operation was aborted"},
 	{"PR_IN_PROGRESS_ERROR",    "Operation is still in progress (probably a non-blocking connect)"},
 	{"PR_ALREADY_INITIATED_ERROR",    "Operation has already been initiated (probably a non-blocking connect)"},
 	{"PR_GROUP_EMPTY_ERROR",    "The wait group is empty"},
 	{"PR_INVALID_STATE_ERROR",    "Object state improper for request"},
 	{"PR_NETWORK_DOWN_ERROR",    "Network is down"},
 	{"PR_SOCKET_SHUTDOWN_ERROR",    "Socket shutdown"},
 	{"PR_CONNECT_ABORTED_ERROR",    "Connection aborted"},
 	{"PR_HOST_UNREACHABLE_ERROR",    "Host is unreachable"},
--- a/pr/src/misc/prerr.et
+++ b/pr/src/misc/prerr.et
@@ -94,17 +94,17 @@ ec PR_MAX_DIRECTORY_ENTRIES_ERROR,
 "Directory is full.  No additional filenames may be added"
 ec PR_INVALID_DEVICE_STATE_ERROR,
 "The required device was in an invalid state"
 ec PR_DEVICE_IS_LOCKED_ERROR, "The device is locked"
 ec PR_NO_MORE_FILES_ERROR,      "No more entries in the directory"
 ec PR_END_OF_FILE_ERROR,        "Encountered end of file"
 ec PR_FILE_SEEK_ERROR,  "Seek error"
 ec PR_FILE_IS_BUSY_ERROR,       "The file is busy"
-ec PR_RESERVED_ERROR_5935,       "Reserved Error Code -5935"
+ec PR_OPERATION_ABORTED_ERROR,  "The I/O operation was aborted"
 ec PR_IN_PROGRESS_ERROR,
 "Operation is still in progress (probably a non-blocking connect)"
 ec PR_ALREADY_INITIATED_ERROR,
 "Operation has already been initiated (probably a non-blocking connect)"
 ec PR_GROUP_EMPTY_ERROR,        "The wait group is empty"
 ec PR_INVALID_STATE_ERROR,      "Object state improper for request"
 ec PR_NETWORK_DOWN_ERROR,       "Network is down"
 ec PR_SOCKET_SHUTDOWN_ERROR,    "Socket shutdown"
--- a/pr/src/misc/prerr.properties
+++ b/pr/src/misc/prerr.properties
@@ -77,17 +77,17 @@ PR_DIRECTORY_CORRUPTED_ERROR=The directo
 PR_FILE_EXISTS_ERROR=Cannot create or rename a filename that already exists
 PR_MAX_DIRECTORY_ENTRIES_ERROR=Directory is full.  No additional filenames may be added
 PR_INVALID_DEVICE_STATE_ERROR=The required device was in an invalid state
 PR_DEVICE_IS_LOCKED_ERROR=The device is locked
 PR_NO_MORE_FILES_ERROR=No more entries in the directory
 PR_END_OF_FILE_ERROR=Encountered end of file
 PR_FILE_SEEK_ERROR=Seek error
 PR_FILE_IS_BUSY_ERROR=The file is busy
-PR_RESERVED_ERROR_5935=Reserved Error Code -5935
+PR_OPERATION_ABORTED_ERROR=The I/O operation was aborted
 PR_IN_PROGRESS_ERROR=Operation is still in progress (probably a non-blocking connect)
 PR_ALREADY_INITIATED_ERROR=Operation has already been initiated (probably a non-blocking connect)
 PR_GROUP_EMPTY_ERROR=The wait group is empty
 PR_INVALID_STATE_ERROR=Object state improper for request
 PR_NETWORK_DOWN_ERROR=Network is down
 PR_SOCKET_SHUTDOWN_ERROR=Socket shutdown
 PR_CONNECT_ABORTED_ERROR=Connection aborted
 PR_HOST_UNREACHABLE_ERROR=Host is unreachable
--- a/pr/src/misc/prerror.c
+++ b/pr/src/misc/prerror.c
@@ -28,22 +28,16 @@ PR_IMPLEMENT(PRErrorCode) PR_GetError()
 }
 
 PR_IMPLEMENT(PRInt32) PR_GetOSError()
 {
     PRThread *thread = PR_GetCurrentThread();
     return thread->osErrorCode;
 }
 
-PR_IMPLEMENT(const char*) PR_GetErrorString()
-{
-    PRThread *thread = PR_GetCurrentThread();
-    return thread->errorString;
-}
-
 PR_IMPLEMENT(void) PR_SetError(PRErrorCode code, PRInt32 osErr)
 {
     PRThread *thread = PR_GetCurrentThread();
     thread->errorCode = code;
     thread->osErrorCode = osErr;
     thread->errorStringSize = 0;
     PR_DELETE(thread->errorString);
 }
--- a/pr/src/misc/prinit.c
+++ b/pr/src/misc/prinit.c
@@ -73,21 +73,21 @@ static void _PR_InitCallOnce(void);
 PRBool _pr_initialized = PR_FALSE;
 
 
 PR_IMPLEMENT(PRBool) PR_VersionCheck(const char *importedVersion)
 {
     /*
     ** This is the secret handshake algorithm.
     **
-    ** This release (3.1) is backward compatible with
-    ** all the previous releases ("2.1 19980529", "3.0",
-    ** "3.0.x").  It is not compatible with future
-    ** releases or patches.  So this release has a
-    ** simple version compatibility check algorithm.
+    ** This release has a simple version compatibility
+    ** check algorithm.  This release is not backward
+    ** compatible with previous major releases.  It is
+    ** not compatible with future major, minor, or
+    ** patch releases.
     */
     int vmajor = 0, vminor = 0, vpatch = 0;
     const char *ptr = importedVersion;
 
     while (isdigit(*ptr)) {
         vmajor = 10 * vmajor + *ptr - '0';
         ptr++;
     }
@@ -101,17 +101,17 @@ PR_IMPLEMENT(PRBool) PR_VersionCheck(con
             ptr++;
             while (isdigit(*ptr)) {
                 vpatch = 10 * vpatch + *ptr - '0';
                 ptr++;
             }
         }
     }
 
-    if (vmajor > PR_VMAJOR) {
+    if (vmajor != PR_VMAJOR) {
         return PR_FALSE;
     }
     if (vmajor == PR_VMAJOR && vminor > PR_VMINOR) {
         return PR_FALSE;
     }
     if (vmajor == PR_VMAJOR && vminor == PR_VMINOR && vpatch > PR_VPATCH) {
         return PR_FALSE;
     }
@@ -139,16 +139,20 @@ static void _pr_SetNativeThreadsOnlyMode
     if (globalp) {
         _native_threads_only = (*globalp != PR_FALSE);
     } else if (envp = getenv("NSPR_NATIVE_THREADS_ONLY")) {
         _native_threads_only = (atoi(envp) == 1);
     }
 }
 #endif
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+extern PRStatus _pr_init_ipv6();
+#endif
+
 static void _PR_InitStuff(void)
 {
 
     if (_pr_initialized) return;
     _pr_initialized = PR_TRUE;
 #ifdef WINNT
     _pr_SetNativeThreadsOnlyMode();
 #endif
@@ -215,16 +219,20 @@ static void _PR_InitStuff(void)
     _PR_InitLinker();
     _PR_InitCallOnce();
     _PR_InitDtoa();
     _PR_InitMW();
     _PR_InitRWLocks();
 
     nspr_InitializePRErrorTable();
 
+#if !defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+	_pr_init_ipv6();
+#endif
+	
     _PR_MD_FINAL_INIT();
 }
 
 void _PR_ImplicitInitialization()
 {
 	_PR_InitStuff();
 
     /* Enable interrupts */
--- a/pr/src/misc/prnetdb.c
+++ b/pr/src/misc/prnetdb.c
@@ -90,23 +90,64 @@ static sigset_t timer_set;
 #define _PR_HAVE_GETPROTO_R
 #define _PR_HAVE_5_ARG_GETPROTO_R
 #endif
 
 #if !defined(_PR_HAVE_GETPROTO_R)
 PRLock* _getproto_lock = NULL;
 #endif
 
-#if defined(_PR_INET6)
-PRBool _pr_ipv6_enabled = PR_FALSE;
-#if defined(AIX)
-const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
-const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
-#endif /* AIX */
-#endif /* _PR_INET6 */
+#if defined(_PR_INET6_PROBE)
+PR_EXTERN(PRBool) _pr_ipv6_is_present;
+#endif
+
+#define _PR_IN6_IS_ADDR_UNSPECIFIED(a)				\
+				(((a)->pr_s6_addr32[0] == 0) &&	\
+				((a)->pr_s6_addr32[1] == 0) &&		\
+				((a)->pr_s6_addr32[2] == 0) &&		\
+				((a)->pr_s6_addr32[3] == 0))
+ 
+#define _PR_IN6_IS_ADDR_LOOPBACK(a)					\
+               (((a)->pr_s6_addr32[0] == 0)	&&	\
+               ((a)->pr_s6_addr32[1] == 0)		&&	\
+               ((a)->pr_s6_addr32[2] == 0)		&&	\
+               ((a)->pr_s6_addr[12] == 0)		&&	\
+               ((a)->pr_s6_addr[13] == 0)		&&	\
+               ((a)->pr_s6_addr[14] == 0)		&&	\
+               ((a)->pr_s6_addr[15] == 0x1U))
+ 
+const PRIPv6Addr _pr_in6addr_any =	{   0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0,
+										0, 0, 0, 0 };
+
+const PRIPv6Addr _pr_in6addr_loopback = {   0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0,
+											0, 0, 0, 0x1U };
+/*
+ * The values at bytes 10 and 11 are compared using pointers to
+ * 8-bit fields, and not 32-bit fields, to make the comparison work on
+ * both big-endian and little-endian systems
+ */
+
+#define _PR_IN6_IS_ADDR_V4MAPPED(a)			\
+		(((a)->pr_s6_addr32[0] == 0) 	&&	\
+		((a)->pr_s6_addr32[1] == 0)	&&	\
+		((a)->pr_s6_addr[8] == 0)		&&	\
+		((a)->pr_s6_addr[9] == 0)		&&	\
+		((a)->pr_s6_addr[10] == 0xff)	&&	\
+		((a)->pr_s6_addr[11] == 0xff))
+
+#define _PR_IN6_IS_ADDR_V4COMPAT(a)			\
+		(((a)->pr_s6_addr32[0] == 0) &&	\
+		((a)->pr_s6_addr32[1] == 0) &&		\
+		((a)->pr_s6_addr32[2] == 0))
+
+#define _PR_IN6_V4MAPPED_TO_IPADDR(a) ((a)->pr_s6_addr32[3])
 
 void _PR_InitNet(void)
 {
 #if defined(XP_UNIX)
 #ifdef HAVE_NETCONFIG
 	/*
 	 * This one-liner prevents the endless re-open's and re-read's of
 	 * /etc/netconfig on EACH and EVERY call to accept(), connect(), etc.
@@ -117,41 +158,16 @@ void _PR_InitNet(void)
 	sigaddset(&timer_set, SIGALRM);
 #endif
 #if !defined(_PR_NO_PREEMPT)
 	_pr_dnsLock = PR_NewLock();
 #endif
 #if !defined(_PR_HAVE_GETPROTO_R)
 	_getproto_lock = PR_NewLock();
 #endif
-
-}
-
-PR_IMPLEMENT(PRStatus) PR_SetIPv6Enable(PRBool itIs)
-{
-#if defined(XP_MAC)
-#pragma unused (itIs)
-#endif
-
-#if defined(_PR_INET6)
-    _pr_ipv6_enabled = itIs;
-    return PR_SUCCESS;
-#else /* defined(_PR_INET6) */
-    PR_SetError(PR_PROTOCOL_NOT_SUPPORTED_ERROR, 0);
-    return PR_FAILURE;
-#endif /* defined(_PR_INET6) */
-}  /* PR_SetIPv6Enable */
-
-PR_IMPLEMENT(PRStatus) PR_GetHostName(char *name, PRUint32 namelen)
-{
-#if defined(DEBUG)
-    static PRBool warn = PR_TRUE;
-    if (warn) warn = _PR_Obsolete("PR_GetHostName()", "PR_GetSystemInfo()");
-#endif
-    return PR_GetSystemInfo(PR_SI_HOSTNAME, name, namelen);
 }
 
 /*
 ** Allocate space from the buffer, aligning it to "align" before doing
 ** the allocation. "align" must be a power of 2.
 */
 static char *Alloc(PRIntn amount, char **bufp, PRIntn *buflenp, PRIntn align)
 {
@@ -169,134 +185,123 @@ static char *Alloc(PRIntn amount, char *
 	if (buflen < amount) {
 		return 0;
 	}
 	*bufp = buf + amount;
 	*buflenp = buflen - amount;
 	return buf;
 }
 
-#if defined(_PR_INET6)
-
 typedef enum _PRIPAddrConversion {
     _PRIPAddrNoConversion,
     _PRIPAddrIPv4Mapped,
     _PRIPAddrIPv4Compat
 } _PRIPAddrConversion;
 
 /*
 ** Convert an IPv4 address (v4) to an IPv4-mapped IPv6 address (v6).
 */
 static void MakeIPv4MappedAddr(const char *v4, char *v6)
 {
     memset(v6, 0, 10);
     memset(v6 + 10, 0xff, 2);
     memcpy(v6 + 12, v4, 4);
-    PR_ASSERT(IN6_IS_ADDR_V4MAPPED((struct in6_addr *) v6));
+    PR_ASSERT(_PR_IN6_IS_ADDR_V4MAPPED(((PRIPv6Addr *) v6)));
 }
 
 /*
 ** Convert an IPv4 address (v4) to an IPv4-compatible IPv6 address (v6).
 */
 static void MakeIPv4CompatAddr(const char *v4, char *v6)
 {
     memset(v6, 0, 12);
     memcpy(v6 + 12, v4, 4);
-    PR_ASSERT(IN6_IS_ADDR_V4COMPAT((struct in6_addr *) v6));
+    PR_ASSERT(_PR_IN6_IS_ADDR_V4COMPAT(((PRIPv6Addr *) v6)));
 }
 
-#endif /* _PR_INET6 */
-
 /*
 ** Copy a hostent, and all of the memory that it refers to into
 ** (hopefully) stacked buffers.
 */
 static PRStatus CopyHostent(
     struct hostent *from,
-    char *buf,
-    PRIntn bufsize,
-#if defined(_PR_INET6)
+    char **buf,
+    PRIntn *bufsize,
     _PRIPAddrConversion conversion,
-#endif
     PRHostEnt *to)
 {
 	PRIntn len, na;
 	char **ap;
 
-	/* Do the easy stuff */
-#if defined(_PR_INET6)
 	if (conversion != _PRIPAddrNoConversion
 			&& from->h_addrtype == AF_INET) {
 		PR_ASSERT(from->h_length == 4);
-		to->h_addrtype = AF_INET6;
+		to->h_addrtype = PR_AF_INET6;
 		to->h_length = 16;
 	} else {
-		to->h_addrtype = from->h_addrtype;
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (AF_INET6 == from->h_addrtype)
+			to->h_addrtype = PR_AF_INET6;
+		else
+#endif
+			to->h_addrtype = from->h_addrtype;
 		to->h_length = from->h_length;
 	}
-#else
-	to->h_addrtype = from->h_addrtype;
-	to->h_length = from->h_length;
-#endif
 
 	/* Copy the official name */
 	if (!from->h_name) return PR_FAILURE;
 	len = strlen(from->h_name) + 1;
-	to->h_name = Alloc(len, &buf, &bufsize, 0);
+	to->h_name = Alloc(len, buf, bufsize, 0);
 	if (!to->h_name) return PR_FAILURE;
 	memcpy(to->h_name, from->h_name, len);
 
 	/* Count the aliases, then allocate storage for the pointers */
 	if (!from->h_aliases) {
 		na = 1;
 	} else {
 		for (na = 1, ap = from->h_aliases; *ap != 0; na++, ap++){;} /* nothing to execute */
 	}
 	to->h_aliases = (char**)Alloc(
-	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
 	if (!to->h_aliases) return PR_FAILURE;
 
 	/* Copy the aliases, one at a time */
 	if (!from->h_aliases) {
 		to->h_aliases[0] = 0;
 	} else {
 		for (na = 0, ap = from->h_aliases; *ap != 0; na++, ap++) {
 			len = strlen(*ap) + 1;
-			to->h_aliases[na] = Alloc(len, &buf, &bufsize, 0);
+			to->h_aliases[na] = Alloc(len, buf, bufsize, 0);
 			if (!to->h_aliases[na]) return PR_FAILURE;
 			memcpy(to->h_aliases[na], *ap, len);
 		}
 		to->h_aliases[na] = 0;
 	}
 
 	/* Count the addresses, then allocate storage for the pointers */
 	for (na = 1, ap = from->h_addr_list; *ap != 0; na++, ap++){;} /* nothing to execute */
 	to->h_addr_list = (char**)Alloc(
-	    na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+	    na * sizeof(char*), buf, bufsize, sizeof(char**));
 	if (!to->h_addr_list) return PR_FAILURE;
 
 	/* Copy the addresses, one at a time */
 	for (na = 0, ap = from->h_addr_list; *ap != 0; na++, ap++) {
-		to->h_addr_list[na] = Alloc(to->h_length, &buf, &bufsize, 0);
+		to->h_addr_list[na] = Alloc(to->h_length, buf, bufsize, 0);
 		if (!to->h_addr_list[na]) return PR_FAILURE;
-#if defined(_PR_INET6)
 		if (conversion != _PRIPAddrNoConversion
 				&& from->h_addrtype == AF_INET) {
 			if (conversion == _PRIPAddrIPv4Mapped) {
 				MakeIPv4MappedAddr(*ap, to->h_addr_list[na]);
 			} else {
 				PR_ASSERT(conversion == _PRIPAddrIPv4Compat);
 				MakeIPv4CompatAddr(*ap, to->h_addr_list[na]);
 			}
 		} else {
 			memcpy(to->h_addr_list[na], *ap, to->h_length);
 		}
-#else
-		memcpy(to->h_addr_list[na], *ap, to->h_length);
-#endif
 	}
 	to->h_addr_list[na] = 0;
 	return PR_SUCCESS;
 }
 
 #if !defined(_PR_HAVE_GETPROTO_R)
 /*
 ** Copy a protoent, and all of the memory that it refers to into
@@ -340,260 +345,325 @@ static PRStatus CopyProtoent(
 PR_IMPLEMENT(PRStatus) PR_GetHostByName(
     const char *name, char *buf, PRIntn bufsize, PRHostEnt *hp)
 {
 	struct hostent *h;
 	PRStatus rv = PR_FAILURE;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-	int error_num;
-#endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
 
-#ifdef _PR_INET6
-    if (_pr_ipv6_enabled)
-    {
-#ifdef _PR_HAVE_GETHOSTBYNAME2
-        h = gethostbyname2(name, AF_INET6);
-        if (NULL == h)
-        {
-            h = gethostbyname2(name, AF_INET);
-        }
-#elif defined(_PR_HAVE_GETIPNODEBYNAME)
-        h = getipnodebyname(name, AF_INET6, AI_DEFAULT, &error_num);
-#else
-#error "Unknown name-to-address translation function"
-#endif
-    }
-    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)
 	{
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
-#else
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
-#endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
-
-		if (_pr_ipv6_enabled) conversion = _PRIPAddrIPv4Mapped;
-		rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
-		rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
 		if (PR_SUCCESS != rv)
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
-		freehostent(h);
-#endif
 	}
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
 
+#if defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+typedef struct hostent  * (*_pr_getipnodebyname_t)(const char *, int,
+										int, int *);
+typedef struct hostent  * (*_pr_getipnodebyaddr_t)(const void *, size_t,
+													int, int *);
+typedef void (*_pr_freehostent_t)(struct hostent *);
+extern void * _pr_getipnodebyname_fp;
+extern void * _pr_getipnodebyaddr_fp;
+extern void * _pr_freehostent_fp;
+#endif
+
 PR_IMPLEMENT(PRStatus) PR_GetIPNodeByName(
     const char *name, PRUint16 af, PRIntn flags,
     char *buf, PRIntn bufsize, PRHostEnt *hp)
 {
-	struct hostent *h;
+	struct hostent *h = 0;
 	PRStatus rv = PR_FAILURE;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	PRUint16 md_af = af;
 	int error_num;
+	int tmp_flags = 0;
+#endif
+#if defined(_PR_HAVE_GETHOSTBYNAME2)
+    PRBool did_af_inet = PR_FALSE;
+    char **new_addr_list;
 #endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
-#if defined(_PR_INET6)
-    PR_ASSERT(af == AF_INET || af == AF_INET6);
-    if (af != AF_INET && af != AF_INET6) {
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-        return PR_FAILURE;
-    }
-#else
-    PR_ASSERT(af == AF_INET);
-    if (af != AF_INET) {
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-        return PR_FAILURE;
-    }
-#endif
-
-    /*
-     * Flags other than PR_AI_DEFAULT are not yet supported.
-     */
-    PR_ASSERT(flags == PR_AI_DEFAULT);
-    if (flags != PR_AI_DEFAULT) {
+    PR_ASSERT(af == PR_AF_INET || af == PR_AF_INET6);
+    if (af != PR_AF_INET && af != PR_AF_INET6) {
         PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
         return PR_FAILURE;
     }
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
 
+#if defined(_PR_HAVE_GETIPNODEBYNAME)
+	if (flags & PR_AI_V4MAPPED)
+		tmp_flags |= AI_V4MAPPED;
+	if (flags & PR_AI_ADDRCONFIG)
+		tmp_flags |= AI_ADDRCONFIG;
+	if (flags & PR_AI_ALL)
+		tmp_flags |= AI_ALL;
+    if (af == PR_AF_INET6)
+    	md_af = AF_INET6;
+	else
+    	md_af = af;
+#endif
+
 #ifdef _PR_INET6
 #ifdef _PR_HAVE_GETHOSTBYNAME2
-    if (af == AF_INET6)
+    if (af == PR_AF_INET6)
     {
-        h = gethostbyname2(name, af); 
-        if (NULL == h)
+#ifdef _PR_INET6_PROBE
+      if (_pr_ipv6_is_present == PR_TRUE)
+#endif
+        h = gethostbyname2(name, AF_INET6); 
+        if ((NULL == h) && (flags & PR_AI_V4MAPPED))
         {
+            did_af_inet = PR_TRUE;
             h = gethostbyname2(name, AF_INET);
         }
     }
     else
     {
+        did_af_inet = PR_TRUE;
         h = gethostbyname2(name, af);
     }
 #elif defined(_PR_HAVE_GETIPNODEBYNAME)
-    h = getipnodebyname(name, af, AI_DEFAULT, &error_num);
+    h = getipnodebyname(name, md_af, tmp_flags, &error_num);
 #else
 #error "Unknown name-to-address translation function"
-#endif
+#endif	/* _PR_HAVE_GETHOSTBYNAME2 */
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    	h = (*((_pr_getipnodebyname_t)_pr_getipnodebyname_fp))(name, md_af, tmp_flags, &error_num);
+	else
+    	h = gethostbyname(name);
 #else /* _PR_INET6 */
 #ifdef XP_OS2_VACPP
 	h = gethostbyname((char *)name);
 #else
     h = gethostbyname(name);
 #endif
 #endif /* _PR_INET6 */
     
 	if (NULL == h)
 	{
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #else
 	    PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
 
-		if (af == AF_INET6) conversion = _PRIPAddrIPv4Mapped;
-		rv = CopyHostent(h, buf, bufsize, conversion, hp);
-#else
-		rv = CopyHostent(h, buf, bufsize, hp);
-#endif
+		if (af == PR_AF_INET6) conversion = _PRIPAddrIPv4Mapped;
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hp);
 		if (PR_SUCCESS != rv)
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYNAME)
 		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYNAME)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
+#endif
+#if defined(_PR_INET6) && defined(_PR_HAVE_GETHOSTBYNAME2)
+		if ((flags & PR_AI_V4MAPPED) && (flags & (PR_AI_ALL|PR_AI_ADDRCONFIG))
+				&& !did_af_inet && (h = gethostbyname2(name, AF_INET)) != 0) {
+			/* Append the V4 addresses to the end of the list */
+			PRIntn na, na_old;
+			char **ap;
+			
+			/* Count the addresses, then grow storage for the pointers */
+			for (na_old = 0, ap = hp->h_addr_list; *ap != 0; na_old++, ap++)
+					{;} /* nothing to execute */
+			for (na = na_old + 1, ap = h->h_addr_list; *ap != 0; na++, ap++)
+					{;} /* nothing to execute */
+			new_addr_list = (char**)Alloc(
+				na * sizeof(char*), &buf, &bufsize, sizeof(char**));
+			if (!new_addr_list) return PR_FAILURE;
+
+			/* Copy the V6 addresses, one at a time */
+			for (na = 0, ap = hp->h_addr_list; *ap != 0; na++, ap++) {
+				new_addr_list[na] = hp->h_addr_list[na];
+			}
+			hp->h_addr_list = new_addr_list;
+
+			/* Copy the V4 addresses, one at a time */
+			for (ap = h->h_addr_list; *ap != 0; na++, ap++) {
+				hp->h_addr_list[na] = Alloc(hp->h_length, &buf, &bufsize, 0);
+				if (!hp->h_addr_list[na]) return PR_FAILURE;
+				MakeIPv4MappedAddr(*ap, hp->h_addr_list[na]);
+			}
+			hp->h_addr_list[na] = 0;
+		}
 #endif
 	}
+
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
 
 PR_IMPLEMENT(PRStatus) PR_GetHostByAddr(
     const PRNetAddr *hostaddr, char *buf, PRIntn bufsize, PRHostEnt *hostentry)
 {
 	struct hostent *h;
 	PRStatus rv = PR_FAILURE;
 	const void *addr;
+	PRUint32 tmp_ip;
 	int addrlen;
+	PRInt32 af;
 #ifdef XP_UNIX
 	sigset_t oldset;
 #endif
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
+#if defined(_PR_HAVE_GETIPNODEBYADDR)
 	int error_num;
 #endif
 
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
 #ifdef XP_UNIX
 	DISABLECLOCK(&oldset);
 #endif
 	LOCK_DNS();
-#if defined(_PR_INET6)
-	if (hostaddr->raw.family == AF_INET6)
+	if (hostaddr->raw.family == PR_AF_INET6)
 	{
-		addr = &hostaddr->ipv6.ip;
-		addrlen = sizeof(hostaddr->ipv6.ip);
+#if defined(_PR_INET6_PROBE)
+		if (_pr_ipv6_is_present == PR_TRUE)
+			af = AF_INET6;
+		else
+			af = AF_INET;
+#elif defined(_PR_INET6)
+		af = AF_INET6;
+#else
+		af = AF_INET;
+#endif
 	}
 	else
-#endif /* defined(_PR_INET6) */
 	{
 		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		af = AF_INET;
+	}
+	if (hostaddr->raw.family == PR_AF_INET6) {
+#if defined(_PR_INET6) || defined(_PR_INET6_PROBE)
+		if (af == AF_INET6) {
+			addr = &hostaddr->ipv6.ip;
+			addrlen = sizeof(hostaddr->ipv6.ip);
+		}
+		else
+#endif
+		{
+			PR_ASSERT(af == AF_INET);
+			if (!_PR_IN6_IS_ADDR_V4MAPPED(&hostaddr->ipv6.ip)) {
+				PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+				return rv;
+			}
+			tmp_ip = _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)
+												&hostaddr->ipv6.ip);
+			addr = &tmp_ip;
+			addrlen = sizeof(tmp_ip);
+		}
+	} else {
+		PR_ASSERT(hostaddr->raw.family == AF_INET);
+		PR_ASSERT(af == AF_INET);
 		addr = &hostaddr->inet.ip;
 		addrlen = sizeof(hostaddr->inet.ip);
 	}
-#if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
-	h = getipnodebyaddr(addr, addrlen, hostaddr->raw.family, &error_num);
-#else
+
+#if defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6)
+	h = getipnodebyaddr(addr, addrlen, af, &error_num);
+#elif defined(_PR_HAVE_GETIPNODEBYADDR) && defined(_PR_INET6_PROBE)
+    if (_pr_ipv6_is_present == PR_TRUE)
+    	h = (*((_pr_getipnodebyaddr_t)_pr_getipnodebyaddr_fp))(addr, addrlen,
+				af, &error_num);
+	else
+		h = gethostbyaddr(addr, addrlen, af);
+#else	/* _PR_HAVE_GETIPNODEBYADDR */
 #ifdef XP_OS2_VACPP
-	h = gethostbyaddr((char *)addr, addrlen, hostaddr->raw.family);
+	h = gethostbyaddr((char *)addr, addrlen, af);
 #else
-	h = gethostbyaddr(addr, addrlen, hostaddr->raw.family);
+	h = gethostbyaddr(addr, addrlen, af);
 #endif
-#endif /* _PR_INET6 && _PR_HAVE_GETIPNODEBYADDR */
+#endif /* _PR_HAVE_GETIPNODEBYADDR */
 	if (NULL == h)
 	{
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
 		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, error_num);
+		else
+	    	PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #else
 		PR_SetError(PR_DIRECTORY_LOOKUP_ERROR, _MD_GETHOST_ERRNO());
 #endif
 	}
 	else
 	{
-#if defined(_PR_INET6)
 		_PRIPAddrConversion conversion = _PRIPAddrNoConversion;
-		if (hostaddr->raw.family == AF_INET6) {
-			if (IN6_IS_ADDR_V4MAPPED((struct in6_addr*)addr)) {
-				conversion = _PRIPAddrIPv4Mapped;
-			} else if (IN6_IS_ADDR_V4COMPAT((struct in6_addr*)addr)) {
-				conversion = _PRIPAddrIPv4Compat;
+		if (hostaddr->raw.family == PR_AF_INET6) {
+			if (af == AF_INET) {
+				if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr*)
+												&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Mapped;
+				} else if (_PR_IN6_IS_ADDR_V4COMPAT((PRIPv6Addr *)
+													&hostaddr->ipv6.ip)) {
+					conversion = _PRIPAddrIPv4Compat;
+				}
 			}
 		}
-		rv = CopyHostent(h, buf, bufsize, conversion, hostentry);
-#else
-		rv = CopyHostent(h, buf, bufsize, hostentry);
-#endif
+		rv = CopyHostent(h, &buf, &bufsize, conversion, hostentry);
 		if (PR_SUCCESS != rv) {
 		    PR_SetError(PR_INSUFFICIENT_RESOURCES_ERROR, 0);
 		}
 #if defined(_PR_INET6) && defined(_PR_HAVE_GETIPNODEBYADDR)
 		freehostent(h);
+#elif defined(_PR_INET6_PROBE) && defined(_PR_HAVE_GETIPNODEBYADDR)
+    	if (_pr_ipv6_is_present == PR_TRUE)
+			(*((_pr_freehostent_t)_pr_freehostent_fp))(h);
 #endif
 	}
 	UNLOCK_DNS();
 #ifdef XP_UNIX
 	ENABLECLOCK(&oldset);
 #endif
 	return rv;
 }
@@ -802,19 +872,21 @@ PR_IMPLEMENT(PRUintn) PR_NetAddrSize(con
      * struct sockaddr_in6.  PRNetAddr's ipv6 member has a
      * scope_id field to match the new field.  In order to
      * work with older implementations supporting RFC 2133,
      * we take the size of struct sockaddr_in6 instead of
      * addr->ipv6.
      */
     if (AF_INET == addr->raw.family)
         addrsize = sizeof(addr->inet);
+    else if (PR_AF_INET6 == addr->raw.family)
 #if defined(_PR_INET6)
-    else if (AF_INET6 == addr->raw.family)
         addrsize = sizeof(struct sockaddr_in6);
+#else
+        addrsize = sizeof(addr->ipv6);
 #endif
 #if defined(XP_UNIX)
     else if (AF_UNIX == addr->raw.family)
         addrsize = sizeof(addr->local);
 #endif
     else addrsize = 0;
 
     return addrsize;
@@ -824,110 +896,86 @@ PR_IMPLEMENT(PRIntn) PR_EnumerateHostEnt
     PRIntn enumIndex, const PRHostEnt *hostEnt, PRUint16 port, PRNetAddr *address)
 {
     void *addr = hostEnt->h_addr_list[enumIndex++];
     memset(address, 0, sizeof(PRNetAddr));
     if (NULL == addr) enumIndex = 0;
     else
     {
         address->raw.family = hostEnt->h_addrtype;
-#if defined(_PR_INET6)
-        if (AF_INET6 == hostEnt->h_addrtype)
+        if (PR_AF_INET6 == hostEnt->h_addrtype)
         {
             address->ipv6.port = htons(port);
+        	address->ipv6.flowinfo = 0;
+        	address->ipv6.scope_id = 0;
             memcpy(&address->ipv6.ip, addr, hostEnt->h_length);
         }
         else
-#endif /* defined(_PR_INET6) */
         {
             PR_ASSERT(AF_INET == hostEnt->h_addrtype);
             address->inet.port = htons(port);
             memcpy(&address->inet.ip, addr, hostEnt->h_length);
         }
     }
     return enumIndex;
 }  /* PR_EnumerateHostEnt */
 
 PR_IMPLEMENT(PRStatus) PR_InitializeNetAddr(
     PRNetAddrValue val, PRUint16 port, PRNetAddr *addr)
 {
     PRStatus rv = PR_SUCCESS;
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
-#if defined(_PR_INET6)
-    if (_pr_ipv6_enabled)
-    {
-        addr->ipv6.family = AF_INET6;
-        addr->ipv6.port = htons(port);
-        switch (val)
-        {
-        case PR_IpAddrNull:
-            break;  /* don't overwrite the address */
-        case PR_IpAddrAny:
-            addr->ipv6.ip = in6addr_any;
-            break;
-        case PR_IpAddrLoopback:
-            addr->ipv6.ip = in6addr_loopback;
-            break;
-        default:
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            rv = PR_FAILURE;
-        }
-    }
-    else
-#endif  /* defined(_PR_INET6) */
-    {
-        addr->inet.family = AF_INET;
-        addr->inet.port = htons(port);
-        switch (val)
-        {
-        case PR_IpAddrNull:
-            break;  /* don't overwrite the address */
-        case PR_IpAddrAny:
-            addr->inet.ip = htonl(INADDR_ANY);
-            break;
-        case PR_IpAddrLoopback:
-            addr->inet.ip = htonl(INADDR_LOOPBACK);
-            break;
-        default:
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-            rv = PR_FAILURE;
-        }
-    }
+	addr->inet.family = AF_INET;
+	addr->inet.port = htons(port);
+	switch (val)
+	{
+	case PR_IpAddrNull:
+		break;  /* don't overwrite the address */
+	case PR_IpAddrAny:
+		addr->inet.ip = htonl(INADDR_ANY);
+		break;
+	case PR_IpAddrLoopback:
+		addr->inet.ip = htonl(INADDR_LOOPBACK);
+		break;
+	default:
+		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+		rv = PR_FAILURE;
+	}
     return rv;
 }  /* PR_InitializeNetAddr */
 
 PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
     PRNetAddrValue val, PRUint16 af, PRUint16 port, PRNetAddr *addr)
 {
     PRStatus rv = PR_SUCCESS;
     if (!_pr_initialized) _PR_ImplicitInitialization();
 
     addr->raw.family = af;
-#if defined(_PR_INET6)
-    if (af == AF_INET6)
+    if (af == PR_AF_INET6)
     {
         addr->ipv6.port = htons(port);
+        addr->ipv6.flowinfo = 0;
+        addr->ipv6.scope_id = 0;
         switch (val)
         {
         case PR_IpAddrNull:
             break;  /* don't overwrite the address */
         case PR_IpAddrAny:
-            addr->ipv6.ip = in6addr_any;
+            addr->ipv6.ip = _pr_in6addr_any;
             break;
         case PR_IpAddrLoopback:
-            addr->ipv6.ip = in6addr_loopback;
+            addr->ipv6.ip = _pr_in6addr_loopback;
             break;
         default:
             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
             rv = PR_FAILURE;
         }
     }
     else
-#endif  /* defined(_PR_INET6) */
     {
         addr->inet.port = htons(port);
         switch (val)
         {
         case PR_IpAddrNull:
             break;  /* don't overwrite the address */
         case PR_IpAddrAny:
             addr->inet.ip = htonl(INADDR_ANY);
@@ -941,75 +989,302 @@ PR_IMPLEMENT(PRStatus) PR_SetNetAddr(
         }
     }
     return rv;
 }  /* PR_SetNetAddr */
 
 PR_IMPLEMENT(PRBool)
 PR_IsNetAddrType(const PRNetAddr *addr, PRNetAddrValue val)
 {
-#if defined(_PR_INET6)
-    if (addr->raw.family == AF_INET6) {
-        if (val == PR_IpAddrAny
-                && IN6_IS_ADDR_UNSPECIFIED((struct in6_addr*)&addr->ipv6.ip)) {
-            return PR_TRUE;
-        } else if (val == PR_IpAddrLoopback
-                && IN6_IS_ADDR_LOOPBACK((struct in6_addr*)&addr->ipv6.ip)) {
+    if (addr->raw.family == PR_AF_INET6) {
+        if (val == PR_IpAddrAny) {
+			if (_PR_IN6_IS_ADDR_UNSPECIFIED((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_ANY)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrLoopback) {
+            if (_PR_IN6_IS_ADDR_LOOPBACK((PRIPv6Addr *)&addr->ipv6.ip)) {
+            	return PR_TRUE;
+			} else if (_PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)
+					&& _PR_IN6_V4MAPPED_TO_IPADDR((PRIPv6Addr *)&addr->ipv6.ip)
+							== htonl(INADDR_LOOPBACK)) {
+            	return PR_TRUE;
+			}
+        } else if (val == PR_IpAddrV4Mapped
+                && _PR_IN6_IS_ADDR_V4MAPPED((PRIPv6Addr *)&addr->ipv6.ip)) {
             return PR_TRUE;
         }
-    }
-    else
-#endif
-    {
+    } else {
         if (addr->raw.family == AF_INET) {
             if (val == PR_IpAddrAny && addr->inet.ip == htonl(INADDR_ANY)) {
                 return PR_TRUE;
             } else if (val == PR_IpAddrLoopback
                     && addr->inet.ip == htonl(INADDR_LOOPBACK)) {
                 return PR_TRUE;
             }
         }
     }
     return PR_FALSE;
 }
 
-PR_IMPLEMENT(PRNetAddr*) PR_CreateNetAddr(PRNetAddrValue val, PRUint16 port)
+#ifndef _PR_INET6
+#define XX 127
+static const unsigned char index_hex[256] = {
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+     0, 1, 2, 3,  4, 5, 6, 7,  8, 9,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,10,11,12, 13,14,15,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+    XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX, XX,XX,XX,XX,
+};
+
+/*
+ * StringToV6Addr() returns 1 if the conversion succeeds,
+ * or 0 if the input is not a valid IPv6 address string.
+ * (Same as inet_pton(AF_INET6, string, addr).)
+ */
+static int StringToV6Addr(const char *string, PRIPv6Addr *addr)
 {
-    PRNetAddr *addr = NULL;
-    if ((PR_IpAddrAny == val) || (PR_IpAddrLoopback == val))
-    {
-        addr = PR_NEWZAP(PRNetAddr);
-        if (NULL == addr)
-            PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
-        else
-            if (PR_FAILURE == PR_InitializeNetAddr(val, port, addr))
-                PR_DELETE(addr);  /* and that will make 'addr' == NULL */
+    const unsigned char *s = (const unsigned char *)string;
+    int section = 0;        /* index of the current section (a 16-bit
+                             * piece of the address */
+    int double_colon = -1;  /* index of the section after the first
+                             * 16-bit group of zeros represented by
+                             * the double colon */
+    unsigned int val;
+    int len;
+
+    /* Handle initial (double) colon */
+    if (*s == ':') {
+        if (s[1] != ':') return 0;
+        s += 2;
+        addr->pr_s6_addr16[0] = 0;
+        section = double_colon = 1;
+    }
+
+    while (*s) {
+        if (section == 8) return 0; /* too long */
+        if (*s == ':') {
+            if (double_colon != -1) return 0; /* two double colons */
+            addr->pr_s6_addr16[section++] = 0;
+            double_colon = section;
+            s++;
+            continue;
+        }
+        for (len = val = 0; len < 4 && index_hex[*s] != XX; len++) {
+            val = (val << 4) + index_hex[*s++];
+        }
+        if (*s == '.') {
+            if (len == 0) return 0; /* nothing between : and . */
+            break;
+        }
+        if (*s == ':') {
+            s++;
+            if (!*s) return 0; /* cannot end with single colon */
+        } else if (*s) {
+            return 0; /* bad character */
+        }
+        addr->pr_s6_addr16[section++] = htons((unsigned short)val);
+    }
+    
+    if (*s == '.') {
+        /* Have a trailing v4 format address */
+        if (section > 6) return 0; /* not enough room */
+
+        /*
+         * The number before the '.' is decimal, but we parsed it
+         * as hex.  That means it is in BCD.  Check it for validity
+         * and convert it to binary.
+         */
+        if (val > 0x0255 || (val & 0xf0) > 0x90 || (val & 0xf) > 9) return 0;
+        val = (val >> 8) * 100 + ((val >> 4) & 0xf) * 10 + (val & 0xf);
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s != '.') return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section] = val;
+
+        s++;
+        val = index_hex[*s++];
+        if (val > 9) return 0;
+        while (*s >= '0' && *s <= '9') {
+            val = val * 10 + *s++ - '0';
+            if (val > 255) return 0;
+        }
+        if (*s) return 0; /* must have exactly 4 decimal numbers */
+        addr->pr_s6_addr[2 * section + 1] = val;
+        section++;
+    }
+    
+    if (double_colon != -1) {
+        /* Stretch the double colon */
+        int tosection;
+        int ncopy = section - double_colon;
+        for (tosection = 7; ncopy--; tosection--) {
+            addr->pr_s6_addr16[tosection] = 
+                addr->pr_s6_addr16[double_colon + ncopy];
+        }
+        while (tosection >= double_colon) {
+            addr->pr_s6_addr16[tosection--] = 0;
+        }
+    } else if (section != 8) {
+        return 0; /* too short */
     }
-    else
-        PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
-    return addr;
-}  /* PR_CreateNetAddr */
+    return 1;
+}
+#undef XX
+            
+static const char *basis_hex = "0123456789abcdef";
+
+/*
+ * V6AddrToString() returns a pointer to the buffer containing
+ * the text string if the conversion succeeds, and NULL otherwise.
+ * (Same as inet_ntop(AF_INET6, addr, buf, size), except that errno
+ * is not set on failure.)
+ */
+static const char *V6AddrToString(
+    const PRIPv6Addr *addr, char *buf, PRUint32 size)
+{
+#define STUFF(c) do { \
+    if (!size--) return NULL; \
+    *buf++ = (c); \
+} while (0)
+
+    int double_colon = -1;          /* index of the first 16-bit
+                                     * group of zeros represented
+                                     * by the double colon */
+    int double_colon_length = 1;    /* use double colon only if
+                                     * there are two or more 16-bit
+                                     * groups of zeros */
+    int zero_length;
+    int section;
+    unsigned int val;
+    const char *bufcopy = buf;
+
+    /* Scan to find the placement of the double colon */
+    for (section = 0; section < 8; section++) {
+        if (addr->pr_s6_addr16[section] == 0) {
+            zero_length = 1;
+            section++;
+            while (section < 8 && addr->pr_s6_addr16[section] == 0) {
+                zero_length++;
+                section++;
+            }
+            /* Select the longest sequence of zeros */
+            if (zero_length > double_colon_length) {
+                double_colon = section - zero_length;
+                double_colon_length = zero_length;
+            }
+        }
+    }
+
+    /* Now start converting to a string */
+    section = 0;
 
-PR_IMPLEMENT(PRStatus) PR_DestroyNetAddr(PRNetAddr *addr)
-{
-    PR_Free(addr);
-    return PR_SUCCESS;
-}  /* PR_DestroyNetAddr */
+    if (double_colon == 0) {
+        if (double_colon_length == 6 ||
+            (double_colon_length == 5 && addr->pr_s6_addr16[5] == 0xffff)) {
+            /* ipv4 format address */
+            STUFF(':');
+            STUFF(':');
+            if (double_colon_length == 5) {
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF('f');
+                STUFF(':');
+            }
+            if (addr->pr_s6_addr[12] > 99) STUFF(addr->pr_s6_addr[12]/100 + '0');
+            if (addr->pr_s6_addr[12] > 9) STUFF((addr->pr_s6_addr[12]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[12]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[13] > 99) STUFF(addr->pr_s6_addr[13]/100 + '0');
+            if (addr->pr_s6_addr[13] > 9) STUFF((addr->pr_s6_addr[13]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[13]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[14] > 99) STUFF(addr->pr_s6_addr[14]/100 + '0');
+            if (addr->pr_s6_addr[14] > 9) STUFF((addr->pr_s6_addr[14]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[14]%10 + '0');
+            STUFF('.');
+            if (addr->pr_s6_addr[15] > 99) STUFF(addr->pr_s6_addr[15]/100 + '0');
+            if (addr->pr_s6_addr[15] > 9) STUFF((addr->pr_s6_addr[15]%100)/10 + '0');
+            STUFF(addr->pr_s6_addr[15]%10 + '0');
+            STUFF('\0');
+            return bufcopy;
+        }
+    }
+
+    while (section < 8) {
+        if (section == double_colon) {
+            STUFF(':');
+            STUFF(':');
+            section += double_colon_length;
+            continue;
+        }
+        val = ntohs(addr->pr_s6_addr16[section]);
+        if (val > 0xfff) {
+            STUFF(basis_hex[val >> 12]);
+        }
+        if (val > 0xff) {
+            STUFF(basis_hex[(val >> 8) & 0xf]);
+        }
+        if (val > 0xf) {
+            STUFF(basis_hex[(val >> 4) & 0xf]);
+        }
+        STUFF(basis_hex[val & 0xf]);
+        section++;
+        if (section < 8 && section != double_colon) STUFF(':');
+    }
+    STUFF('\0');
+    return bufcopy;
+#undef STUFF    
+}
+
+#endif /* !_PR_INET6 */
 
 PR_IMPLEMENT(PRStatus) PR_StringToNetAddr(const char *string, PRNetAddr *addr)
 {
     PRStatus status = PR_SUCCESS;
+    PRIntn rv;
 
 #if defined(_PR_INET6)
-    PRIntn rv;
-
     rv = inet_pton(AF_INET6, string, &addr->ipv6.ip);
     if (1 == rv)
     {
-        addr->raw.family = AF_INET6;
+        addr->raw.family = PR_AF_INET6;
     }
     else
     {
         PR_ASSERT(0 == rv);
         rv = inet_pton(AF_INET, string, &addr->inet.ip);
         if (1 == rv)
         {
             addr->raw.family = AF_INET;
@@ -1017,16 +1292,23 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAdd
         else
         {
             PR_ASSERT(0 == rv);
             PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
             status = PR_FAILURE;
         }
     }
 #else /* _PR_INET6 */
+    rv = StringToV6Addr(string, &addr->ipv6.ip);
+    if (1 == rv) {
+        addr->raw.family = PR_AF_INET6;
+        return PR_SUCCESS;
+    }
+    PR_ASSERT(0 == rv);
+
     addr->inet.family = AF_INET;
 #ifdef XP_OS2_VACPP
     addr->inet.ip = inet_addr((char *)string);
 #else
     addr->inet.ip = inet_addr(string);
 #endif
     if ((PRUint32) -1 == addr->inet.ip)
     {
@@ -1039,27 +1321,30 @@ PR_IMPLEMENT(PRStatus) PR_StringToNetAdd
 #endif /* _PR_INET6 */
 
     return status;
 }
 
 PR_IMPLEMENT(PRStatus) PR_NetAddrToString(
     const PRNetAddr *addr, char *string, PRUint32 size)
 {
-#if defined(_PR_INET6)
-    if (AF_INET6 == addr->raw.family)
+    if (PR_AF_INET6 == addr->raw.family)
     {
+#if defined(_PR_INET6)
         if (NULL == inet_ntop(AF_INET6, &addr->ipv6.ip, string, size))
+#else
+        if (NULL == V6AddrToString(&addr->ipv6.ip, string, size))
+#endif
         {
-            PR_SetError(PR_INVALID_ARGUMENT_ERROR, errno);
+            /* the size of the result buffer is inadequate */
+            PR_SetError(PR_BUFFER_OVERFLOW_ERROR, 0);
             return PR_FAILURE;
         }
     }
     else
-#endif  /* defined(_PR_INET6) */
     {
         PR_ASSERT(AF_INET == addr->raw.family);
         PR_ASSERT(size >= 16);
         if (size < 16) goto failed;
         if (AF_INET != addr->raw.family) goto failed;
         else
         {
             unsigned char *byte = (unsigned char*)&addr->inet.ip;
@@ -1071,62 +1356,63 @@ PR_IMPLEMENT(PRStatus) PR_NetAddrToStrin
     return PR_SUCCESS;
 
 failed:
     PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
     return PR_FAILURE;
 
 }  /* PR_NetAddrToString */
 
+/*
+ * Convert an IPv4 addr to an (IPv4-mapped) IPv6 addr
+ */
+PR_IMPLEMENT(void) PR_ConvertIPv4AddrToIPv6(PRUint32 v4addr, PRIPv6Addr *v6addr)
+{
+    PRUint8 *dstp;
+    dstp = v6addr->pr_s6_addr;
+    memset(dstp, 0, 10);
+    memset(dstp + 10, 0xff, 2);
+    memcpy(dstp + 12,(char *) &v4addr, 4);
+}
+
 PR_IMPLEMENT(PRUint16) PR_ntohs(PRUint16 n) { return ntohs(n); }
 PR_IMPLEMENT(PRUint32) PR_ntohl(PRUint32 n) { return ntohl(n); }
 PR_IMPLEMENT(PRUint16) PR_htons(PRUint16 n) { return htons(n); }
 PR_IMPLEMENT(PRUint32) PR_htonl(PRUint32 n) { return htonl(n); }
 PR_IMPLEMENT(PRUint64) PR_ntohll(PRUint64 n)
 {
-    /*
-    ** There is currently no attempt to optomize out depending
-    ** on the host' byte order. That would be easy enough to
-    ** do.
-    */
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
     PRUint64 tmp;
     PRUint32 hi, lo;
     LL_L2UI(lo, n);
     LL_SHR(tmp, n, 32);
     LL_L2UI(hi, tmp);
     hi = PR_ntohl(hi);
     lo = PR_ntohl(lo);
-    LL_UI2L(n, hi);
+    LL_UI2L(n, lo);
     LL_SHL(n, n, 32);
-    LL_UI2L(tmp, lo);
+    LL_UI2L(tmp, hi);
     LL_ADD(n, n, tmp);
     return n;
+#endif
 }  /* ntohll */
 
 PR_IMPLEMENT(PRUint64) PR_htonll(PRUint64 n)
 {
-    /*
-    ** There is currently no attempt to optomize out depending
-    ** on the host' byte order. That would be easy enough to
-    ** do.
-    */
+#ifdef IS_BIG_ENDIAN
+    return n;
+#else
     PRUint64 tmp;
     PRUint32 hi, lo;
     LL_L2UI(lo, n);
     LL_SHR(tmp, n, 32);
     LL_L2UI(hi, tmp);
     hi = htonl(hi);
     lo = htonl(lo);
-    LL_UI2L(n, hi);
+    LL_UI2L(n, lo);
     LL_SHL(n, n, 32);
-    LL_UI2L(tmp, lo);
+    LL_UI2L(tmp, hi);
     LL_ADD(n, n, tmp);
     return n;
+#endif
 }  /* htonll */
-
-PR_IMPLEMENT(PRUint16) PR_FamilyInet(void)
-{
-#ifdef _PR_INET6
-    return (_pr_ipv6_enabled ? AF_INET6 : AF_INET);
-#else
-    return AF_INET;
-#endif
-}
--- a/pr/src/misc/prtpool.c
+++ b/pr/src/misc/prtpool.c
@@ -11,17 +11,16 @@
  * NPL.
  * 
  * The Initial Developer of this code under the NPL is Netscape
  * Communications Corporation.  Portions created by Netscape are
  * Copyright (C) 1999 Netscape Communications Corporation.  All Rights
  * Reserved.
  */
 
-#include "prtpool.h"
 #include "nspr.h"
 
 /*
  * Thread pools
  *	Thread pools create and manage threads to provide support for
  *	scheduling jobs onto one or more threads.
  *
  */
@@ -79,48 +78,45 @@ typedef struct io_jobq {
 /*
  * Threadpool
  */
 struct PRThreadPool {
 	PRInt32		init_threads;
 	PRInt32		max_threads;
 	PRInt32		current_threads;
 	PRInt32		idle_threads;
-	PRInt32		stacksize;
+	PRUint32	stacksize;
 	tp_jobq		jobq;
 	io_jobq		ioq;
 	timer_jobq	timerq;
+	PRLock		*join_lock;		/* used with jobp->join_cv */
 	PRCondVar	*shutdown_cv;
 	PRBool		shutdown;
 };
 
 typedef enum io_op_type
 	{ JOB_IO_READ, JOB_IO_WRITE, JOB_IO_CONNECT, JOB_IO_ACCEPT } io_op_type;
 
-typedef enum _PRJobStatus
-	{ JOB_ON_TIMERQ, JOB_ON_IOQ, JOB_QUEUED, JOB_RUNNING, JOB_COMPLETED,
-					JOB_CANCELED, JOB_FREED } _PRJobStatus;
-
-typedef void (* Jobfn)(void *arg);
-
 #ifdef OPT_WINNT
 typedef struct NT_notifier {
 	OVERLAPPED overlapped;		/* must be first */
 	PRJob	*jobp;
 } NT_notifier;
 #endif
 
 struct PRJob {
 	PRCList			links;		/* 	for linking jobs */
-	_PRJobStatus 	status;
-	PRBool			joinable;
-	Jobfn			job_func;
+	PRBool			on_ioq;		/* job on ioq */
+	PRBool			on_timerq;	/* job on timerq */
+	PRJobFn			job_func;
 	void 			*job_arg;
-	PRLock			*jlock;
 	PRCondVar		*join_cv;
+	PRBool			join_wait;	/* == PR_TRUE, when waiting to join */
+	PRCondVar		*cancel_cv;	/* for cancelling IO jobs */
+	PRBool			cancel_io;	/* for cancelling IO jobs */
 	PRThreadPool	*tpool;		/* back pointer to thread pool */
 	PRJobIoDesc		*iod;
 	io_op_type		io_op;
 	PRInt16			io_poll_flags;
 	PRNetAddr		*netaddr;
 	PRIntervalTime	timeout;	/* relative value */
 	PRIntervalTime	absolute;
 #ifdef OPT_WINNT
@@ -129,23 +125,51 @@ struct PRJob {
 };
 
 #define JOB_LINKS_PTR(_qp) \
     ((PRJob *) ((char *) (_qp) - offsetof(PRJob, links)))
 
 #define WTHREAD_LINKS_PTR(_qp) \
     ((wthread *) ((char *) (_qp) - offsetof(wthread, links)))
 
+#define JOINABLE_JOB(_jobp) (NULL != (_jobp)->join_cv)
+
+#define JOIN_NOTIFY(_jobp)								\
+				PR_BEGIN_MACRO							\
+				PR_Lock(_jobp->tpool->join_lock);		\
+				_jobp->join_wait = PR_FALSE;			\
+				PR_NotifyCondVar(_jobp->join_cv);		\
+				PR_Unlock(_jobp->tpool->join_lock);		\
+				PR_END_MACRO
+
+#define CANCEL_IO_JOB(jobp)								\
+				PR_BEGIN_MACRO							\
+				jobp->cancel_io = PR_FALSE;				\
+				jobp->on_ioq = PR_FALSE;				\
+				PR_REMOVE_AND_INIT_LINK(&jobp->links);	\
+				tp->ioq.cnt--;							\
+				PR_NotifyCondVar(jobp->cancel_cv);		\
+				PR_END_MACRO
+
 static void delete_job(PRJob *jobp);
 static PRThreadPool * alloc_threadpool();
-static PRJob * alloc_job(PRBool joinable);
+static PRJob * alloc_job(PRBool joinable, PRThreadPool *tp);
 static void notify_ioq(PRThreadPool *tp);
 static void notify_timerq(PRThreadPool *tp);
 
 /*
+ * locks are acquired in the following order
+ *
+ *	tp->ioq.lock,tp->timerq.lock
+ *			|
+ *			V
+ *		tp->jobq->lock		
+ */
+
+/*
  * worker thread function
  */
 static void wstart(void *arg)
 {
 PRThreadPool *tp = (PRThreadPool *) arg;
 PRCList *head;
 
 	/*
@@ -167,52 +191,43 @@ PRCList *head;
 		PR_ASSERT(rv);
 		if (shutdown)
 			break;
 		jobp = ((NT_notifier *) olp)->jobp;
 		PR_Lock(tp->jobq.lock);
 		tp->idle_threads--;
 		tp->jobq.cnt--;
 		PR_Unlock(tp->jobq.lock);
-		PR_Lock(jobp->jlock);
-		jobp->status = JOB_RUNNING;
-		PR_Unlock(jobp->jlock);
 #else
 
 		PR_Lock(tp->jobq.lock);
 		while (PR_CLIST_IS_EMPTY(&tp->jobq.list) && (!tp->shutdown)) {
 			tp->idle_threads++;
 			PR_WaitCondVar(tp->jobq.cv, PR_INTERVAL_NO_TIMEOUT);
+			tp->idle_threads--;
 		}	
-		tp->idle_threads--;
 		if (tp->shutdown) {
 			PR_Unlock(tp->jobq.lock);
 			break;
 		}
 		head = PR_LIST_HEAD(&tp->jobq.list);
 		/*
 		 * remove job from queue
 		 */
 		PR_REMOVE_AND_INIT_LINK(head);
 		tp->jobq.cnt--;
 		jobp = JOB_LINKS_PTR(head);
-		PR_Lock(jobp->jlock);
-		jobp->status = JOB_RUNNING;
-		PR_Unlock(jobp->jlock);
 		PR_Unlock(tp->jobq.lock);
 #endif
 
 		jobp->job_func(jobp->job_arg);
-		if (!jobp->joinable) {
+		if (!JOINABLE_JOB(jobp)) {
 			delete_job(jobp);
 		} else {
-			PR_Lock(jobp->jlock);
-			jobp->status = JOB_COMPLETED;
-			PR_NotifyCondVar(jobp->join_cv);
-			PR_Unlock(jobp->jlock);
+			JOIN_NOTIFY(jobp);
 		}
 	}
 	PR_Lock(tp->jobq.lock);
 	tp->current_threads--;
 	PR_Unlock(tp->jobq.lock);
 }
 
 /*
@@ -231,37 +246,39 @@ add_to_jobq(PRThreadPool *tp, PRJob *job
 	/*
 	 * notify worker thread(s)
 	 */
 	PostQueuedCompletionStatus(tp->jobq.nt_completion_port, 0,
             FALSE, &jobp->nt_notifier.overlapped);
 #else
 	PR_Lock(tp->jobq.lock);
 	PR_APPEND_LINK(&jobp->links,&tp->jobq.list);
-	jobp->status = JOB_QUEUED;
 	tp->jobq.cnt++;
 	if ((tp->idle_threads < tp->jobq.cnt) &&
 					(tp->current_threads < tp->max_threads)) {
-		PRThread *thr;
 		wthread *wthrp;
 		/*
 		 * increment thread count and unlock the jobq lock
 		 */
 		tp->current_threads++;
 		PR_Unlock(tp->jobq.lock);
 		/* create new worker thread */
-		thr = PR_CreateThread(PR_USER_THREAD, wstart,
+		wthrp = PR_NEWZAP(wthread);
+		if (wthrp) {
+			wthrp->thread = PR_CreateThread(PR_USER_THREAD, wstart,
 						tp, PR_PRIORITY_NORMAL,
 						PR_GLOBAL_THREAD,PR_JOINABLE_THREAD,tp->stacksize);
+			if (NULL == wthrp->thread) {
+				PR_DELETE(wthrp);  /* this sets wthrp to NULL */
+			}
+		}
 		PR_Lock(tp->jobq.lock);
-		if (NULL == thr) {
+		if (NULL == wthrp) {
 			tp->current_threads--;
 		} else {
-			wthrp = PR_NEWZAP(wthread);
-			wthrp->thread = thr;
 			PR_APPEND_LINK(&wthrp->links, &tp->jobq.wthreads);
 		}
 	}
 	/*
 	 * wakeup a worker thread
 	 */
 	PR_NotifyCondVar(tp->jobq.cv);
 	PR_Unlock(tp->jobq.lock);
@@ -326,16 +343,20 @@ PRIntervalTime now;
 		polljobs[pollfds_used] = NULL;
 		pollfds_used++;
 		/*
 		 * fill in the pollfd array
 		 */
 		PR_Lock(tp->ioq.lock);
 		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
 			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
 			if (pollfds_used == (pollfd_cnt))
 				break;
 			pollfds[pollfds_used].fd = jobp->iod->socket;
 			pollfds[pollfds_used].in_flags = jobp->io_poll_flags;
 			pollfds[pollfds_used].out_flags = 0;
 			polljobs[pollfds_used] = jobp;
 
 			pollfds_used++;
@@ -386,61 +407,88 @@ PRIntervalTime now;
 			}
 
 			for(index = 1; index < (pollfds_used); index++) {
                 PRInt16 events = pollfds[index].in_flags;
                 PRInt16 revents = pollfds[index].out_flags;	
 				jobp = polljobs[index];	
 
                 if ((revents & PR_POLL_NVAL) ||  /* busted in all cases */
+                	(revents & PR_POLL_ERR) ||
                 			((events & PR_POLL_WRITE) &&
 							(revents & PR_POLL_HUP))) { /* write op & hup */
 					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
 					PR_REMOVE_AND_INIT_LINK(&jobp->links);
 					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
 					PR_Unlock(tp->ioq.lock);
 
 					/* set error */
                     if (PR_POLL_NVAL & revents)
 						jobp->iod->error = PR_BAD_DESCRIPTOR_ERROR;
                     else if (PR_POLL_HUP & revents)
 						jobp->iod->error = PR_CONNECT_RESET_ERROR;
+                    else 
+						jobp->iod->error = PR_IO_ERROR;
 
 					/*
 					 * add to jobq
 					 */
 					add_to_jobq(tp, jobp);
-				} else if (revents & events) {
+				} else if (revents) {
 					/*
 					 * add to jobq
 					 */
 					PR_Lock(tp->ioq.lock);
+					if (jobp->cancel_io) {
+						CANCEL_IO_JOB(jobp);
+						PR_Unlock(tp->ioq.lock);
+						continue;
+					}
 					PR_REMOVE_AND_INIT_LINK(&jobp->links);
 					tp->ioq.cnt--;
+					jobp->on_ioq = PR_FALSE;
 					PR_Unlock(tp->ioq.lock);
 
-					jobp->iod->error = 0;
+					if (jobp->io_op == JOB_IO_CONNECT) {
+						if (PR_GetConnectStatus(&pollfds[index]) == PR_SUCCESS)
+							jobp->iod->error = 0;
+						else
+							jobp->iod->error = PR_GetError();
+					} else
+						jobp->iod->error = 0;
+
 					add_to_jobq(tp, jobp);
 				}
 			}
 		}
 		/*
 		 * timeout processing
 		 */
 		now = PR_IntervalNow();
 		PR_Lock(tp->ioq.lock);
 		for (qp = tp->ioq.list.next; qp != &tp->ioq.list; qp = qp->next) {
 			jobp = JOB_LINKS_PTR(qp);
+			if (jobp->cancel_io) {
+				CANCEL_IO_JOB(jobp);
+				continue;
+			}
 			if (PR_INTERVAL_NO_TIMEOUT == jobp->timeout)
 				break;
 			if ((PR_INTERVAL_NO_WAIT != jobp->timeout) &&
 								((PRInt32)(jobp->absolute - now) > 0))
 				break;
 			PR_REMOVE_AND_INIT_LINK(&jobp->links);
 			tp->ioq.cnt--;
+			jobp->on_ioq = PR_FALSE;
 			jobp->iod->error = PR_IO_TIMEOUT_ERROR;
 			add_to_jobq(tp, jobp);
 		}
 		PR_Unlock(tp->ioq.lock);
 	}
 }
 
 /*
@@ -489,32 +537,35 @@ PRIntervalTime now;
 			if ((PRInt32)(jobp->absolute - now) > 0) {
 				break;
 			}
 			/*
 			 * job timed out
 			 */
 			PR_REMOVE_AND_INIT_LINK(&jobp->links);
 			tp->timerq.cnt--;
+			jobp->on_timerq = PR_FALSE;
 			add_to_jobq(tp, jobp);
 		}
 		PR_Unlock(tp->timerq.lock);
 	}
 }
 
 static void
 delete_threadpool(PRThreadPool *tp)
 {
 	if (NULL != tp) {
 		if (NULL != tp->shutdown_cv)
 			PR_DestroyCondVar(tp->shutdown_cv);
 		if (NULL != tp->jobq.cv)
 			PR_DestroyCondVar(tp->jobq.cv);
 		if (NULL != tp->jobq.lock)
 			PR_DestroyLock(tp->jobq.lock);
+		if (NULL != tp->join_lock)
+			PR_DestroyLock(tp->join_lock);
 #ifdef OPT_WINNT
 		if (NULL != tp->jobq.nt_completion_port)
 			CloseHandle(tp->jobq.nt_completion_port);
 #endif
 		/* Timer queue */
 		if (NULL != tp->timerq.cv)
 			PR_DestroyCondVar(tp->timerq.cv);
 		if (NULL != tp->timerq.lock)
@@ -540,16 +591,19 @@ PRThreadPool *tp;
 	if (NULL == tp)
 		goto failed;
 	tp->jobq.lock = PR_NewLock();
 	if (NULL == tp->jobq.lock)
 		goto failed;
 	tp->jobq.cv = PR_NewCondVar(tp->jobq.lock);
 	if (NULL == tp->jobq.cv)
 		goto failed;
+	tp->join_lock = PR_NewLock();
+	if (NULL == tp->join_lock)
+		goto failed;
 #ifdef OPT_WINNT
 	tp->jobq.nt_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE,
 									NULL, 0, 0);
 	if (NULL == tp->jobq.nt_completion_port)
 		goto failed;
 #endif
 
 	tp->ioq.lock = PR_NewLock();
@@ -576,17 +630,17 @@ failed:
 	delete_threadpool(tp);
 	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
 	return NULL;
 }
 
 /* Create thread pool */
 PR_IMPLEMENT(PRThreadPool *)
 PR_CreateThreadPool(PRInt32 initial_threads, PRInt32 max_threads,
-                                PRSize stacksize)
+                                PRUint32 stacksize)
 {
 PRThreadPool *tp;
 PRThread *thr;
 int i;
 wthread *wthrp;
 
 	tp = alloc_threadpool();
 	if (NULL == tp)
@@ -638,42 +692,39 @@ wthread *wthrp;
 	PR_Unlock(tp->jobq.lock);
 	return tp;
 }
 
 static void
 delete_job(PRJob *jobp)
 {
 	if (NULL != jobp) {
-		if (NULL != jobp->jlock) {
-			PR_DestroyLock(jobp->jlock);
-			jobp->jlock = NULL;
-		}
 		if (NULL != jobp->join_cv) {
 			PR_DestroyCondVar(jobp->join_cv);
 			jobp->join_cv = NULL;
 		}
-		jobp->status = JOB_FREED;
+		if (NULL != jobp->cancel_cv) {
+			PR_DestroyCondVar(jobp->cancel_cv);
+			jobp->cancel_cv = NULL;
+		}
 		PR_DELETE(jobp);
 	}
 }
 
 static PRJob *
-alloc_job(PRBool joinable)
+alloc_job(PRBool joinable, PRThreadPool *tp)
 {
 	PRJob *jobp;
 
 	jobp = PR_NEWZAP(PRJob);
 	if (NULL == jobp) 
 		goto failed;
-	jobp->jlock = PR_NewLock();
-	if (NULL == jobp->jlock)
-		goto failed;
 	if (joinable) {
-		jobp->join_cv = PR_NewCondVar(jobp->jlock);
+		jobp->join_cv = PR_NewCondVar(tp->join_lock);
+		jobp->join_wait = PR_TRUE;
 		if (NULL == jobp->join_cv)
 			goto failed;
 	} else {
 		jobp->join_cv = NULL;
 	}
 #ifdef OPT_WINNT
 	jobp->nt_notifier.jobp = jobp;
 #endif
@@ -681,69 +732,66 @@ alloc_job(PRBool joinable)
 failed:
 	delete_job(jobp);
 	PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
 	return NULL;
 }
 
 /* queue a job */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob(PRThreadPool *tpool, JobFn fn, void *arg, PRBool joinable)
+PR_QueueJob(PRThreadPool *tpool, PRJobFn fn, void *arg, PRBool joinable)
 {
 	PRJob *jobp;
 
-	jobp = alloc_job(joinable);
+	jobp = alloc_job(joinable, tpool);
 	if (NULL == jobp)
 		return NULL;
 
 	jobp->job_func = fn;
 	jobp->job_arg = arg;
 	jobp->tpool = tpool;
-	jobp->joinable = joinable;
 
 	add_to_jobq(tpool, jobp);
 	return jobp;
 }
 
-/* queue a job, when a socket is readable */
+/* queue a job, when a socket is readable or writeable */
 static PRJob *
-queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+queue_io_job(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
 				PRBool joinable, io_op_type op)
 {
 	PRJob *jobp;
 	PRIntervalTime now;
 
-	jobp = alloc_job(joinable);
+	jobp = alloc_job(joinable, tpool);
 	if (NULL == jobp) {
 		return NULL;
 	}
 
 	/*
 	 * Add a new job to io_jobq
 	 * wakeup io worker thread
 	 */
 
 	jobp->job_func = fn;
 	jobp->job_arg = arg;
-	jobp->status = JOB_ON_IOQ;
 	jobp->tpool = tpool;
-	jobp->joinable = joinable;
 	jobp->iod = iod;
 	if (JOB_IO_READ == op) {
 		jobp->io_op = JOB_IO_READ;
 		jobp->io_poll_flags = PR_POLL_READ;
 	} else if (JOB_IO_WRITE == op) {
 		jobp->io_op = JOB_IO_WRITE;
 		jobp->io_poll_flags = PR_POLL_WRITE;
 	} else if (JOB_IO_ACCEPT == op) {
 		jobp->io_op = JOB_IO_ACCEPT;
 		jobp->io_poll_flags = PR_POLL_READ;
 	} else if (JOB_IO_CONNECT == op) {
 		jobp->io_op = JOB_IO_CONNECT;
-		jobp->io_poll_flags = PR_POLL_WRITE;
+		jobp->io_poll_flags = PR_POLL_WRITE|PR_POLL_EXCEPT;
 	} else {
 		delete_job(jobp);
 		PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
 		return NULL;
 	}
 
 	jobp->timeout = iod->timeout;
 	if ((PR_INTERVAL_NO_TIMEOUT == iod->timeout) ||
@@ -773,101 +821,114 @@ queue_io_job(PRThreadPool *tpool, PRJobI
 			tmp_jobp = JOB_LINKS_PTR(qp);
 			if ((PRInt32)(jobp->absolute - tmp_jobp->absolute) >= 0) {
 				break;
 			}
 		}
 		PR_INSERT_AFTER(&jobp->links,qp);
 	}
 
+	jobp->on_ioq = PR_TRUE;
 	tpool->ioq.cnt++;
 	/*
 	 * notify io worker thread(s)
 	 */
 	PR_Unlock(tpool->ioq.lock);
 	notify_ioq(tpool);
 	return jobp;
 }
 
 /* queue a job, when a socket is readable */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn, void * arg,
+PR_QueueJob_Read(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn, void * arg,
 											PRBool joinable)
 {
 	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_READ));
 }
 
 /* queue a job, when a socket is writeable */
 PR_IMPLEMENT(PRJob *)
-PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, JobFn fn,void * arg,
+PR_QueueJob_Write(PRThreadPool *tpool, PRJobIoDesc *iod, PRJobFn fn,void * arg,
 										PRBool joinable)
 {
 	return (queue_io_job(tpool, iod, fn, arg, joinable, JOB_IO_WRITE));